如何从派生类调用重载的父cout友元类?

时间:2017-06-19 22:07:56

标签: c++ class oop c++11 inheritance

想象一下如下设置。如何从派生类cout中调用基类cout?我可以使用getBrand()方法,但我觉得我应该能够直接访问基类' 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

4 个答案:

答案 0 :(得分:6)

您可以从派生类调用Base类的重载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

答案 1 :(得分:2)

投下它,像这样:

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

    return out;
}

答案 2 :(得分:2)

所有其他答案都正确回答您的具体问题,但每当您尝试使用这样的多态时:

Brand const &c = Cheese("Cabot Clothbound", "Cheddar");
std::cout << c << std::endl;
将调用与operator <<对应的

Brand,而不是Cheese

这样做的好方法是使用虚拟的 print 成员函数:

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

然后,您只需要一个operator <<作为基类,它将调用您的print虚拟成员函数:

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

DEMO

答案 3 :(得分: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;
}