2017-06-19 50 views
6

想象一下如下设置。如何从派生类cout中调用基类cout?我可以使用getBrand()方法,但我觉得我应该能够直接访问基类'cout朋友函数。如何从派生类中调用重载的父cout朋友类?

我砍了一下,试了this.Brand,也只是Brand。没有运气。

class Brand { 
public: 
    Brand(std::string brand):brand_(brand) {}; 
    friend std::ostream & operator << (std::ostream & out, const Brand & b) { 
     out << b.brand_ << ' '; 
     return out; 
    } 
    std::string getBrand()const { return brand_; }  
private: 
    std::string brand_; 
} 

class Cheese : public Brand { 
public: 
    Cheese(std::string brand, std::string type):Brand(brand), type_(type) {}; 
    friend std::ostream & operator << (std::ostream & out, const Cheese & c) { 
     out << /* THIS.BRAND?! BRAND?! getBrand() meh.. */ << ' ' << c.type_ << std::endl; // <-- HERE 
     return out; 
    } 
private: 
    std::string type_; 
} 

int main() { 
    Cheese c("Cabot Clothbound", "Cheddar"); 
    std::cout << c << std::endl; 
} 

所需的输出

Cabot Clothbound Cheddar 
+0

当Brand的'operator <<'将尾部换行放入流中时,输出应该如何成为'Cabot Clothbound Cheddar'? – Zereges

+0

好点,但在旁边。编辑并删除。 – kmiklas

回答

6

你可以从你的派生类中调用基类的重载operator <<。因为,你声明的运营商作为一个朋友,你可以简单地把派生类的基类:

class Cheese : public Brand { 
public: 
    Cheese(std::string brand, std::string type):Brand(brand), type_(type) {}; 
    friend std::ostream & operator << (std::ostream & out, const Cheese & c) { 

     //ADDED 
     out << static_cast<const Brand&>(c) << c.type_ << std::endl; 
     return out; 
    } 
private: 
    std::string type_; 
}; 

输出:

Cabot Clothbound Cheddar 

See it Live

+0

比你快1分钟,但你有一个现场演示,而我没有一个,所以采取我的upvote。 =) – gsamaras

2

演员,就像这样:

friend std::ostream& operator<<(std::ostream& out, const Cheese& c) 
{ 
    out << static_cast<const Brand &>(c); 
    out << c.type_ << std::endl; 

    return out; 
} 
1

显然,你不能这样做类似于Brand::operator<<,因为operator<<定义为friend,因此它们不是成员函数。

如果你想调用operator<<(std::ostream&, const Brand&),你只需要通过正确的类型这一点,因为派生类可以很容易地铸造到基类,你可以做

friend std::ostream & operator << (std::ostream & out, const Cheese & c) { 
    out << static_cast<const Brand&>(c) << ' ' << c.type_ << std::endl; 
    return out; 
} 
2

其他所有的答案都正确响应你的具体问题,但每当你尝试使用多态是这样的:

Brand const &c = Cheese("Cabot Clothbound", "Cheddar"); 
std::cout << c << std::endl; 

operator <<对应Brand将被调用,而不是Cheese的。

好办法做到这一点是使用虚拟打印成员函数:

class Brand { 
public: 
    Brand(std::string const & brand):brand_(brand) {} 
    virtual ~Brand() {} 
    virtual void print(std::ostream & out) const { 
     out << brand_; 
    } 
    std::string const & getBrand()const { return brand_; }  
private: 
    std::string brand_; 
}; 
class Cheese : public Brand { 
public: 
    Cheese(std::string const & brand, std::string const & type):Brand(brand), type_(type) {} 
    void print(std::ostream & out) const override { 
     Brand::print(out); // calling base print() 
     out << ' ' << type_ << std::endl; 
    } 
private: 
    std::string type_; 
}; 

然后,你只需要在基类,它会叫你printoperator <<虚拟会员功能:

std::ostream & operator << (std::ostream & out, const Brand & b) { 
    b.print(out); 
    return out; 
} 

DEMO

+0

优秀的回应;这次真是万分感谢。尽管它没有像上述那样直接回答问题,但我非常想要接受这个答案。无论如何,感谢您花时间教我这个,我很感激。 :^) – kmiklas