2013-07-12 56 views
1

我有歸結爲允許在派生類

class interface 
{ 
    protected: 
     virtual void write(std::string const &) = 0; 
}; 

和派生類,如

class derived : public interface 
{ 
    protected: 
     void write(std::string const & buf) 
     { 
      std::cout << buf << std::endl; 
     } 
}; 

在我的應用程序的接口,這些對象被傳來傳去的智能指針流運算符,即std::shared_ptr<derived> 。我希望我可以超載<<運營商,但只能用於我的界面衍生品的智能指針。我嘗試這樣做:

class interface 
{ 
    /* ... */ 
    private: 
     template <typename Derived> friend typename std::enable_if< 
      std::is_base_of<interface, Derived>::value, 
      std::shared_ptr<Derived> 
     >::type & operator<<(std::shared_ptr<Derived> & lhs, 
       std::string const & rhs) 
     { 
      lhs->write(rhs); 
      return lhs; 
     } 
}; 

但是當我嘗試std::shared_ptr<derived> sp; sp << "test";,編譯器會抱怨說virtual void derived::write(const string&) is protected within this contextthis context是我的朋友的功能)。

有沒有一種方法可以實現這一點,而無需爲每個派生類冗餘寫入流運算符?

+0

爲什麼'write'是'protected'的任何原因?從你發佈的內容來看,它只有副作用,所以沒有理由把它從用戶身上隱藏起來。特別是因爲用戶無論如何都能夠通過ostream插入器觀察所有這些副作用。 – ComicSansMS

+0

由於'write'是虛擬的,並且在運算符體中'lhs'包含可以轉換爲'interface *'的Derived *',所以可以「向上傳播」(不是直接引用shared_ptr引用,而是底層指針):http ://ideone.com/lqZ2o8(但是就像@ user2362671所說的那樣,你可以使用'std :: shared_ptr sp(new derived)'代替) –

+0

@ComicSansMS我想保持公共API儘可能乾淨,並且gx_的解決方案似乎準確地說,還是有沒有解決方案的缺點,我沒有看到? – user2573221

回答

0

爲什麼不能簡單地定義你的操作爲:

friend std::shared_ptr<interface> &operator<<(std::shared_ptr<interface> & lhs, std::string const & rhs); 

,並通過你的對象爲std::shared_ptr<interface>

+0

我想過,但現有的代碼庫限制了我提供這兩種選擇。 – user2573221

+0

@ user2573221爲什麼?在'derived'中是否有必須調用的函數在'base'中聲明爲虛擬? –

+0

'derived'中的函數在'base'中根本沒有聲明 – user2573221