2015-11-03 111 views
0

我试图实现一种虚拟运算符< <,它允许我发送IBase类对象给cout,以便它调用Derived类的运算符< <。这可能吗?Virtual 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; 
} 

回答

0

的< <操作者是一个函数,而不是一个方法,因此它不能是虚拟的。然而,你仍然可以实现你想要的 - 请记住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

0

你的目标无法通过模板来实现单独作为废弃一个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); 
} 
0

你可以把它虚拟的真正简单的模板台(其中,此外,并不妨碍去的帮助虚拟化)。

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); 
}