2

The first class is:

class SistemPornire{
protected:
    Motor &_motor;
    Electromotor &_electromotor;

public:
    SistemPornire(Motor&,Electromotor&);
    virtual void pornire_motor();
    void opreste_motor();
};

The implementation of the virtual function is:

SistemPornire::SistemPornire(Motor &motor, Electromotor &electromotor)
    :_motor(motor), _electromotor(electromotor)
{
}

void SistemPornire::pornire_motor()
{
     std::cout << "Sistemul de pornire a trimis comanda porneste_motor electromotorului." << std::endl;
    this->_electromotor.start(_motor);
}

The second class:

class SistemPornireCuPreincalzire:public SistemPornire {
public:
    SistemPornireCuPreincalzire(Motor&,Electromotor&);
    void pornire_motor();
};

Its implementation:

SistemPornireCuPreincalzire::SistemPornireCuPreincalzire(Motor&motor, Electromotor&electromotor)
    : SistemPornire(motor, electromotor)
{

}

void SistemPornireCuPreincalzire::pornire_motor()
{
    std::cout << "A inceput preincalzirea" <<std::endl<< "Preincalzirea incheiata" << std::endl;

    std::cout << "Sistemul de pornire a trimis comanda porneste_motor electromotorului." << std::endl;
    this->_electromotor.start(_motor);
}

In the main function I'm trying to call the function pornire_motor() for an object of type SistemPornireCuPreincalzire yet it would print out the message from the SistemPornire::pornire_motor() function.

Could you please tell me what is it that I am doing wrong? Is the information I have provided sufficient?

class Autoturism {

private:
    Electromotor electromotor;
    Motor motor;
    SistemPornire sistem_pornire;
    SistemDirectie sistem_directie;
    CutieViteze cutieviteze;

public:
    Autoturism(SistemPornire&, Electromotor&, Motor&, SistemDirectie&);
    void porneste_autoturism();
    void condu_la_destinatie();
    void parcheaza_autoturism();
};

Autoturism::Autoturism(SistemPornire &sp, Electromotor&e, Motor&m, SistemDirectie&sd): sistem_pornire(sp), electromotor(e), motor(m), sistem_directie(sd)
{

}

void Autoturism::porneste_autoturism()
{
    std::cout <<  "Comanda porneste_autoturism a fost trimisa catre sistemul de pornire." << std::endl;
    this->sistem_pornire.pornire_motor();
}

void Autoturism::condu_la_destinatie()
{
    this->porneste_autoturism();
    std::cout << "Odata ce masina a pornit, soferul o poate conduce la destinatie." << std::endl;

    this->cutieviteze.gearUp();
    this->sistem_directie.stanga(0);
    this->cutieviteze.gearUp();
    this->cutieviteze.gearUp();
    this->cutieviteze.gearDown();
    this->sistem_directie.stanga(90);
    this->cutieviteze.gearUp();
    this->sistem_directie.stanga(0);
    this->cutieviteze.gearDown();
    this->sistem_directie.dreapta(30);
    this->sistem_directie.dreapta(0);
    this->sistem_directie.dreapta(10);


    std::cout << "Odata ce s-a ajuns la destinatie masina e gata de a fi parcata." << std::endl;
    this->parcheaza_autoturism();
    std::cout << "Soferul a ajuns la destinatie." << std::endl;
}

void Autoturism::parcheaza_autoturism()
{
    std::cout <<  "Comanda parcheaza_autoturism a fost trimisa catre sistemul de pornire." << std::endl;
    this->sistem_pornire.opreste_motor();
}

Main function:

int main()
{
    Motor motor;
    Electromotor electromotor;
    SistemPornire sistempornire(motor, electromotor);
    SistemDirectie sistemdirectie;
    SistemPornireCuPreincalzire sistempornireINC(motor, electromotor);

    Autoturism masina(sistempornireINC, electromotor, motor,sistemdirectie);

    std::cout << "Porneste autoturism:" << std::endl;
    masina.porneste_autoturism();

    std::cout << "Parcheaza autoturism:" << std::endl;
    masina.parcheaza_autoturism();

    std::cout << "Condu la destinatie:" << std::endl;
    masina.condu_la_destinatie();
    return 0;
}
Teodora
  • 687
  • 2
  • 11
  • 21

2 Answers2

5

Let's look at some parts of your code and analyze what is going on. This is your code from main:

Motor motor;
Electromotor electromotor;
SistemPornire sistempornire(motor, electromotor);
SistemDirectie sistemdirectie;
SistemPornireCuPreincalzire sistempornireINC(motor, electromotor);

Notice how you create an instance of SistemPornireCuPreincalzire here which you then pass into the constructor of Autoturism:

Autoturism masina(sistempornireINC, electromotor, motor,sistemdirectie);

Let's look at the constructor of Autoturism for a second, shall we?

Autoturism(SistemPornire&, Electromotor&, Motor&, SistemDirectie&);

Hmm, it takes a reference to a SistemPornire and we're passing a reference to SistemPornireCuPreincalzire. That's not necessarily an error, but it's enough to get you thinking. So let's look at what the Autoturism constructor does:

Autoturism::Autoturism(SistemPornire &sp, Electromotor&e, 
                       Motor&m, SistemDirectie&sd)
    : sistem_pornire(sp), electromotor(e), motor(m), sistem_directie(sd)
{

}

Hmm... what's the type of sistem_pornire? Looking at the code, we see it's declared as:

SistemPornire sistem_pornire;

Just seeing this is enough to explain why virtual functions aren't working. The type of sistem_pornire is known at compile-time and there's no virtual dispatch. Remember, virtual functions happen only when you call a virtual function through a pointer (i.e. you must use the -> operator).

But let's dig a bit deeper too...

So the constructor takes a reference to a SistemPornire instance and uses it to initialize the instance of the sistem_pornire member in Autoturism. In other words, you copy-construct the sistem_pornire object with the SistemPornire part of the SistemPornireCuPreincalzire you declare in main.

The object from main is never called and never used.

You should read carefully about the slicing problem and about virtual functions dispatch in C++.

Good luck!

Community
  • 1
  • 1
Nik Bougalis
  • 10,495
  • 1
  • 21
  • 37
3

edit

In the updated question, as @Roddy points out, slicing occurs in the Autoturism constructor.

You are slicing your objects by assigning a derived object to a base object.

SistemPornireCuPreincalzire derived = SistemPornireCuPreincalzire();

SistemPornire base = derived; // sliced

You need to refer to the derived class by reference:

SistemPornireCuPreincalzire derived = SistemPornireCuPreincalzire();

SistemPornire& base = derived; // no slicing

See:

Community
  • 1
  • 1
Peter Wood
  • 23,859
  • 5
  • 60
  • 99