C++ 面向对象编程重载 ostream 在打印时出现的问题

huangapple go评论58阅读模式
英文:

C++ OOP overloading ostream problem at printing

问题

这是我的代码:

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

他打印的是对象的地址,而不是我写的内容。

我尝试使用 cout << *obiecte[i] << endl;,但是出现了错误。

错误信息如下:

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
英文:

This is my code:

#include &lt;iostream&gt;
#include &lt;cstring&gt;
using namespace std;
class ObiectCosmic{
protected:
char* nume;
float raza;
float masa;
public:
ObiectCosmic(char* nume = &quot;&quot;, float raza = 0.0, float maza = 0.0);
virtual ~ObiectCosmic();
};
ObiectCosmic::ObiectCosmic(char* nume, float raza, float masa){
this-&gt;nume = new char[strlen(nume) + 1];
strcpy(this-&gt;nume, nume);
this-&gt;raza = raza;
this-&gt;masa = masa;
}
ObiectCosmic::~ObiectCosmic(){
delete[] nume;
}
class Planeta: public ObiectCosmic{
private:
float perioadaRotatie;
public:
Planeta(char* nume = &quot;&quot;, float raza = 0.0, float masa = 0.0, float perioadaRotatie = 0.0);
~Planeta();
friend ostream&amp; operator&lt;&lt;(ostream&amp; os, const Planeta&amp; p);
};
Planeta::Planeta(char* nume, float raza, float masa, float perioadaRotatie): ObiectCosmic(nume, raza, masa){
this-&gt;perioadaRotatie = perioadaRotatie;
}
Planeta::~Planeta(){}
ostream&amp; operator&lt;&lt;(ostream&amp; os, const Planeta&amp; p){
os &lt;&lt; &quot;Nume: &quot; &lt;&lt; p.nume &lt;&lt; &quot;, raza: &quot; &lt;&lt; p.raza &lt;&lt; &quot;masa: &quot; &lt;&lt; p.masa &lt;&lt; &quot;, rotatie: &quot; &lt;&lt; p.perioadaRotatie &lt;&lt; endl;
return os;
}
class Stea: public ObiectCosmic{
private:
float stralucire;
public:
Stea(char* nume = &quot;&quot;, float raza = 0.0, float masa = 0.0, float stralucire = 0.0);
~Stea();
friend ostream&amp; operator&lt;&lt;(ostream&amp; os, const Stea&amp; s);
};
Stea::Stea(char* nume, float raza, float masa, float stralucire): ObiectCosmic(nume, raza, masa){
this-&gt;stralucire = stralucire;
}
Stea::~Stea(){}
ostream&amp; operator&lt;&lt;(ostream&amp; os, const Stea&amp; s){
os &lt;&lt; &quot;Nume: &quot; &lt;&lt; s.nume &lt;&lt; &quot;, raza: &quot; &lt;&lt; s.raza &lt;&lt; &quot;masa: &quot; &lt;&lt; s.masa &lt;&lt; &quot;, stralucire: &quot; &lt;&lt; s.stralucire &lt;&lt; endl;
return os;    
}
int main(){
Stea s(&quot;Soare&quot;, 123123.54, 3543454325.2, 343434.132);
Planeta p(&quot;Pamant&quot;, 34132.12, 567546.234, 3545.13);
Planeta p2;
ObiectCosmic* obiecte[] = {
&amp;s,
&amp;p,
&amp;p2
};
for(int i = 0; i &lt; sizeof(obiecte) / sizeof(ObiectCosmic*); i++)
cout &lt;&lt; obiecte[i] &lt;&lt; endl;
return 0;       
}

He is printing the adress of objects instead of what i wrote.

I tried with cout << *obiecte[i] << endl;, but i have an error.

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

答案1

得分: 0

以下是您的代码的问题总结:

  1. 在C++中,字符串字面值具有常量字符数组的类型,所以您需要在构造函数声明中使用const char*,而不是char*,例如:
Stea(const char* nume = "", float raza = 0.0, float masa = 0.0, float stralucire = 0.0);
  1. 数值数据成员应该使用float类型,因此您需要在构造函数中提供float类型的常量,例如:
Stea("Soare", 123123.54f, 3543454325.2f, 343434.132f);
Planeta("Pamant", 34132.12f, 567546.234f, 3545.13f);
  1. 您声明了一个友元函数,它接受类型为Stea的引用:
friend ostream& operator<<(ostream& os, const Stea& s);

但是在尝试调用它时,您却传递了Planeta类型对象的引用,这将导致编译器发出错误,因为没有这样的函数。要使友元运算符<<“虚拟化”,您应该像这样声明它:

friend ostream& operator<<(ostream& os, const Planeta& s);

并在其中调用相应类型的对象的虚拟函数。

这是一个演示程序,展示了上述修复的代码:

#include <iostream>
#include <string>
#include <cstring>

using namespace std;

// ...(其余代码保持不变)

运行此修复后的程序应该得到正确的输出。

英文:

There are several problems with your code.

For starters string literals in C++ have types of constant character arrays.

So for example instead of this constructor declaration

Stea(char* nume = &quot;&quot;, float raza = 0.0, float masa = 0.0, float stralucire = 0.0);

you have to write

Stea( const char* nume = &quot;&quot;, float raza = 0.0, float masa = 0.0, float stralucire = 0.0);

Numerical data members have the the float. So you need to call the constructors providing constants of the type float like for example

Stea s( &quot;Soare&quot;, 123123.54f, 3543454325.2f, 343434.132f );
Planeta p( &quot;Pamant&quot;, 34132.12f, 567546.234f, 3545.13f );

Otherwise the compiler can issue a warining relative to narrowing conversion. Otherwise declare the data members as having the type double.

You declared a friend function that accepts a reference to the type Stea

friend ostream&amp; operator&lt;&lt;(ostream&amp; os, const `Stea`&amp; s);

but trying to call it passing references to objects of the type Planeta. So the compiler issues an error that there is no such a function.

To make the friend operator &lt;&lt; "virtual" you should declare it like

friend ostream&amp; operator&lt;&lt;(ostream&amp; os, const Planeta&amp; s);

and within it call a virtual function of an object of the corresponding type.

Here is a demonstration program.

#include &lt;iostream&gt;
#include &lt;string&gt;
#include &lt;cstring&gt;
using namespace std;
class ObiectCosmic
{
protected:
char *nume;
float raza;
float masa;
virtual std::ostream &amp; out( std::ostream &amp;os = std::cout ) const 
{
return os &lt;&lt; &quot;Nume: &quot; &lt;&lt; nume &lt;&lt; &quot;, raza: &quot; &lt;&lt; raza &lt;&lt; &quot;, masa: &quot; &lt;&lt; masa;
}
public:
ObiectCosmic( const char *nume = &quot;&quot;, float raza = 0.0, float maza = 0.0 );
virtual ~ObiectCosmic();
friend ostream &amp; operator &lt;&lt;( ostream &amp;os, const ObiectCosmic &amp;p );
};
ObiectCosmic::ObiectCosmic( const char *nume, float raza, float masa ) 
{
this-&gt;nume = new char[strlen( nume ) + 1];
strcpy( this-&gt;nume, nume );
this-&gt;raza = raza;
this-&gt;masa = masa;
}
ObiectCosmic::~ObiectCosmic() 
{
delete[] nume;
}
class Planeta : public ObiectCosmic
{
protected:
std::ostream &amp;out( std::ostream &amp;os = std::cout ) const override
{
return  ObiectCosmic:: out( os ) &lt;&lt; &quot;, perioada rotatie: &quot; &lt;&lt; perioadaRotatie;
}
private:
float perioadaRotatie;
public:
Planeta( const char *nume = &quot;&quot;, float raza = 0.0, float masa = 0.0, float perioadaRotatie = 0.0 );
~Planeta();
};
Planeta::Planeta( const char *nume, float raza, float masa, float perioadaRotatie ) : ObiectCosmic( nume, raza, masa ) {
this-&gt;perioadaRotatie = perioadaRotatie;
}
Planeta::~Planeta() {}
ostream &amp;operator&lt;&lt;( ostream &amp;os, const ObiectCosmic &amp;p ) {
return p.out( os );
}
class Stea : public ObiectCosmic
{
private:
float stralucire;
public:
Stea( const char *nume = &quot;&quot;, float raza = 0.0, float masa = 0.0, float stralucire = 0.0 );
~Stea();
};
Stea::Stea( const char *nume, float raza, float masa, float stralucire ) : ObiectCosmic( nume, raza, masa ) {
this-&gt;stralucire = stralucire;
}
Stea::~Stea() {}
int main()
{
Stea s( &quot;Soare&quot;, 123123.54f, 3543454325.2f, 343434.132f );
Planeta p( &quot;Pamant&quot;, 34132.12f, 567546.234f, 3545.13f );
Planeta p2;
ObiectCosmic *obiecte[] = {
&amp;s,
&amp;p,
&amp;p2
};
for (size_t i = 0; i &lt; sizeof( obiecte ) / sizeof( *obiecte ); i++)
cout &lt;&lt; *obiecte[i] &lt;&lt; endl;
}

The program output is

Nume: Soare, raza: 123124, masa: 3.54345e+09
Nume: Pamant, raza: 34132.1, masa: 567546, perioada rotatie: 3545.13
Nume: , raza: 0, masa: 0, perioada rotatie: 0

huangapple
  • 本文由 发表于 2023年5月14日 00:37:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/76243839.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定