Как вызвать перегруженный родительский класс cout friend из производного класса?
Представьте себе такую установку. Как вызвать базовый класс 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 ответа:
Можно вызвать перегруженный
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
Смотрите его вживую
Бросьте его, вот так:
friend std::ostream& operator<<(std::ostream& out, const Cheese& c) { out << static_cast<const Brand &>(c); out << c.type_ << std::endl; return out; }
Все остальные ответы правильно отвечают на ваш конкретный вопрос, но всякий раз, когда вы пытаетесь использовать полиморфизм, как это:
Brand const &c = Cheese("Cabot Clothbound", "Cheddar"); std::cout << c << std::endl;
operator <<
соответствующийBrand
будет называться вместоCheese
' s.Хороший способ сделать это-использовать виртуальную функцию-член 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 <<
для базового класса, который вызовет вашуstd::ostream & operator << (std::ostream & out, const Brand & b) { b.print(out); return out; }
Вы, очевидно, не можете сделать ничего подобного
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; }