0

This is my code:

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

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 '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
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
SimiDragos
  • 23
  • 1

1 Answers1

0

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 = "", float raza = 0.0, float masa = 0.0, float stralucire = 0.0);

you have to write

Stea( const char* nume = "", 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( "Soare", 123123.54f, 3543454325.2f, 343434.132f );
Planeta p( "Pamant", 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& operator<<(ostream& os, const `Stea`& 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 << "virtual" you should declare it like

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

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

Here is a demonstration program.

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

using namespace std;

class ObiectCosmic
{
protected:
    char *nume;
    float raza;
    float masa;

    virtual std::ostream & out( std::ostream &os = std::cout ) const 
    {
        return os << "Nume: " << nume << ", raza: " << raza << ", masa: " << masa;
    }
public:
    ObiectCosmic( const char *nume = "", float raza = 0.0, float maza = 0.0 );
    virtual ~ObiectCosmic();
    friend ostream & operator <<( ostream &os, const ObiectCosmic &p );

};

ObiectCosmic::ObiectCosmic( const 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
{
protected:
std::ostream &out( std::ostream &os = std::cout ) const override
{
    return  ObiectCosmic:: out( os ) << ", perioada rotatie: " << perioadaRotatie;
}

private:
    float perioadaRotatie;
public:
    Planeta( const char *nume = "", 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->perioadaRotatie = perioadaRotatie;
}

Planeta::~Planeta() {}

ostream &operator<<( ostream &os, const ObiectCosmic &p ) {
    return p.out( os );
}

class Stea : public ObiectCosmic
{
private:
    float stralucire;
public:
    Stea( const char *nume = "", 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->stralucire = stralucire;
}

Stea::~Stea() {}

int main()
{
    Stea s( "Soare", 123123.54f, 3543454325.2f, 343434.132f );
    Planeta p( "Pamant", 34132.12f, 567546.234f, 3545.13f );
    Planeta p2;

    ObiectCosmic *obiecte[] = {
        &s,
        &p,
        &p2
    };

    for (size_t i = 0; i < sizeof( obiecte ) / sizeof( *obiecte ); i++)
        cout << *obiecte[i] << 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
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • Beginners should **stay away from raw pointers**. This program will soon **leak memory**, due to violating **rule of 0/3/5**. What's wrong with **`std::string` instead of `char*`**? – Red.Wave May 14 '23 at 12:31
  • @Red.Wave The question is about operator overloading. The question is not about please rewrite all the program for me.:) – Vlad from Moscow May 14 '23 at 15:43
  • RAII is the basis of C++ programming. I do not go further, If the audience is not familiar with basics. It is a deep problem that every newbie just jumps over pointers; and gets himself stuck with problems that could be avoided via correct approach to programming. – Red.Wave May 14 '23 at 16:26
  • @Red.Wave I think you can create your own course on programming. But here there was asked a concrete question about operator overloading. – Vlad from Moscow May 14 '23 at 16:34