我正在尝试实现一种虚拟操作符<<,它允许我向cout发送一个IBase类对象,这样它就可以调用派生类的operator <<。这个是可能的吗?
class IBase
{
public:
IBase() {};
virtual ~IBase() {};
};
template <typename T>
class Derived
: public IBase
{
public:
Derived(T data);
template <typename U>
friend std::ostream& operator<<(std::ostream& os, const Derived<U>& dt);
private:
T data_;
};
template <typename T>
Derived<T>::Derived(T data)
: IBase(),
data_(data)
{
}
template <typename T>
std::ostream& operator<<(std::ostream& os, const Derived<T>& dt)
{
os << dt.data_;
return os;
}
int _tmain(int argc, _TCHAR* argv[])
{
IBase* base = new Derived<int>(5);
std::cout << *base;
}发布于 2015-11-03 18:03:36
<<运算符是一个函数,而不是一个方法,因此它不能是虚拟的。但是,您仍然可以实现您想要的结果--还记得operator<<接受引用作为参数吗?好的,多态也适用于这些。只需添加另一个从<<操作符调用的虚拟方法。
看一下我放在一起的这个简短的例子:
#include <iostream>
#include <string>
using namespace std;
class Base {
public:
virtual string toString() const {
return "base";
}
};
class Child : public Base {
public:
virtual string toString() const {
return "child";
}
friend ostream& operator<<(ostream& out, const Base& b);
};
ostream& operator<<(ostream& out, const Base& b) {
out << b.toString();
return out;
}
int main() {
Child c;
cout << c;
return 0;
}在ideone中有一个链接:http://ideone.com/EmP1oP
发布于 2015-11-03 18:03:42
您的目标不能仅通过模板来实现,因为取消对模板的引用会产生一个IBase& - IBase*实例化发生在编译时,并且编译器无法访问运行时类型。
(动态分派仅在调用对象的成员函数时发生,并且二元运算符不能是其右操作数的成员。)
因此,如果您将一个取消引用的IBase*传递给operator <<,您的模板化运算符将永远不会被使用。
相反,向基础添加一个虚拟输出函数并覆盖它:
class IBase
{
public:
IBase() {};
virtual ~IBase() {};
virtual std::ostream& output(std::ostream&) const = 0;
};
template <typename T>
class Derived
: public IBase
{
public:
Derived(T data);
virtual std::ostream& output(std::ostream& os) const
{
os << data;
return os;
}
private:
T data_;
};
std::ostream& operator<<(std::ostream& os, const IBase& dt)
{
return dt.output(os);
}发布于 2015-11-03 18:05:27
您可以通过简单的模板rig (此外,它不会阻止去虚拟化)的帮助,将其变为真实的虚拟。
struct X {
virtual std::ostream& repr(std::ostream& out) const;
}
template <class X>
std::enable_if_t<
std::is_same<
std::void_t<
decltype(std::declval<X>().repr(std::declval<std::ostream>()))>,
void>::value,
std::ostream&>
operator<<(X const& x)
{
return x.repr(out);
}https://stackoverflow.com/questions/33496137
复制相似问题