2015-11-03 151 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); 
}