You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++ OOP中ostream重载问题:打印对象输出地址而非内容

问题:多态打印宇宙对象时的编译错误

当前程序打印对象地址而非自定义内容,尝试改为cout << *obiecte[i] << endl;后出现编译错误,提示找不到std::ostream与ObiectCosmic的operator<<匹配。

原代码

#include <iostream>
#include <cstring>

using namespace std;

class ObiectCosmic{
    protected:
        char* nume;
        float raza;
        float masa;
    public:
        ObiectCosmic(char* nume = "", float raza = 0.0, float masa = 0.0);
        virtual ~ObiectCosmic();
};

ObiectCosmic::ObiectCosmic(char* nume, float raza, float masa){
    this->nume = new char[strlen(nume) + 1];
    strcpy(this->nume, nume);
    this->raza = raza;
    this->masa = masa;
}

ObiectCosmic::~ObiectCosmic(){
    delete[] nume;
}

class Planeta: public ObiectCosmic{
    private:
        float perioadaRotatie;
    public:
        Planeta(char* nume = "", float raza = 0.0, float masa = 0.0, float perioadaRotatie = 0.0);
        ~Planeta();
        friend ostream& operator<<(ostream& os, const Planeta& p);
};

Planeta::Planeta(char* nume, float raza, float masa, float perioadaRotatie): ObiectCosmic(nume, raza, masa){
    this->perioadaRotatie = perioadaRotatie;
}

Planeta::~Planeta(){}

ostream& operator<<(ostream& os, const Planeta& p){
    os << "Nume: " << p.nume << ", raza: " << p.raza << "masa: " << p.masa << ", rotatie: " << p.perioadaRotatie << endl;
    return os;
}

class Stea: public ObiectCosmic{
    private:
        float stralucire;
    public:
        Stea(char* nume = "", float raza = 0.0, float masa = 0.0, float stralucire = 0.0);
        ~Stea();
        friend ostream& operator<<(ostream& os, const Stea& s);
};

Stea::Stea(char* nume, float raza, float masa, float stralucire): ObiectCosmic(nume, raza, masa){
    this->stralucire = stralucire;
}

Stea::~Stea(){}

ostream& operator<<(ostream& os, const Stea& s){
    os << "Nume: " << s.nume << ", raza: " << s.raza << "masa: " << s.masa << ", stralucire: " << s.stralucire << endl;
    return os;    
}

int main(){
    Stea s("Soare", 123123.54, 3543454325.2, 343434.132);
    Planeta p("Pamant", 34132.12, 567546.234, 3545.13);
    Planeta p2;
    
    ObiectCosmic* obiecte[] = {
        &s,
        &p,
        &p2
    };

    for(int i = 0; i < sizeof(obiecte) / sizeof(ObiectCosmic*); i++)
        cout << obiecte[i] << endl;

    return 0;       
}

编译错误信息

10.cpp:79:14: error: no match for 'operator<<' (operand types are 'std::ostream' {aka 'std::basic_ostream<char>'} and 'ObiectCosmic')
   79 |         cout << *obiecte[i] << endl;
      |         ~~~~ ^~ ~~~~~~~~~~~
      |         |       |     
      |         |       ObiectCosmic
      |         std::ostream {aka 'std::basic_ostream<char>'} 
In file included from C:/msys64/mingw64/include/c++/12.2.0/iostream:39

解决步骤

问题根源是基类ObiectCosmic未定义operator<<,且派生类的operator<<无法通过基类指针触发多态。需通过虚函数实现多态打印:

1. 修改基类ObiectCosmic

添加纯虚打印函数和统一的友元operator<<:

class ObiectCosmic{
    protected:
        char* nume;
        float raza;
        float masa;
    public:
        ObiectCosmic(char* nume = "", float raza = 0.0, float masa = 0.0);
        virtual ~ObiectCosmic();
        // 纯虚函数,派生类必须实现
        virtual void afisare(ostream& os) const = 0;
        // 友元operator<<,调用虚函数实现多态输出
        friend ostream& operator<<(ostream& os, const ObiectCosmic& obj);
};

// 基类operator<<的统一实现
ostream& operator<<(ostream& os, const ObiectCosmic& obj){
    obj.afisare(os);
    return os;
}

2. 修改派生类Planeta

移除原有友元operator<<,重写afisare函数:

class Planeta: public ObiectCosmic{
    private:
        float perioadaRotatie;
    public:
        Planeta(char* nume = "", float raza = 0.0, float masa = 0.0, float perioadaRotatie = 0.0);
        ~Planeta();
        // 重写虚函数
        void afisare(ostream& os) const override;
};

// Planeta的自定义打印逻辑
void Planeta::afisare(ostream& os) const {
    os << "Nume: " << nume << ", raza: " << raza << ", masa: " << masa << ", rotatie: " << perioadaRotatie << endl;
}

3. 修改派生类Stea

同样移除友元operator<<,重写afisare函数:

class Stea: public ObiectCosmic{
    private:
        float stralucire;
    public:
        Stea(char* nume = "", float raza = 0.0, float masa = 0.0, float stralucire = 0.0);
        ~Stea();
        // 重写虚函数
        void afisare(ostream& os) const override;
};

// Stea的自定义打印逻辑
void Stea::afisare(ostream& os) const {
    os << "Nume: " << nume << ", raza: " << raza << ", masa: " << masa << ", stralucire: " << stralucire << endl;
}

4. 调整main函数

使用cout << *obiecte[i] << endl;即可触发多态打印:

for(int i = 0; i < sizeof(obiecte) / sizeof(ObiectCosmic*); i++)
    cout << *obiecte[i] << endl;

原理说明

  • 基类的operator<<作为统一入口,调用纯虚函数afisare,利用多态特性自动匹配派生类的实现。
  • 派生类通过重写afisare实现自定义打印逻辑,避免重复定义operator<<,同时保证基类指针能正确识别派生类对象的打印行为。

内容的提问来源于stack exchange,提问作者SimiDragos

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 01:47:23