2

第一类是:

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

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

虚函数的实现是:

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

第二类:

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

它的实现:

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

在主函数中,我试图为pornire_motor()类型对象调用函数,SistemPornireCuPreincalzire但它会从函数中打印出消息SistemPornire::pornire_motor()

你能告诉我我做错了什么吗?我提供的信息是否足够?

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();
}

主功能:

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

2 回答 2

5

让我们看一下代码的某些部分并分析发生了什么。这是您的代码main

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

请注意如何创建一个SistemPornireCuPreincalzirehere 的实例,然后将其传递给 的构造函数Autoturism

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

让我们看一下 的构造函数,Autoturism好吗?

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

嗯,它需要对 a 的引用SistemPornire而我们正在传递对 的引用SistemPornireCuPreincalzire。这不一定是错误,但足以让您思考。那么让我们看看Autoturism构造函数做了什么:

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

}

嗯……是什么类型的sistem_pornire?查看代码,我们看到它被声明为:

SistemPornire sistem_pornire;

仅仅看到这一点就足以解释为什么虚函数不起作用。的类型sistem_pornire在编译时是已知的,并且没有虚拟调度。请记住,只有当您通过指针调用虚函数时才会发生虚函数(即必须使用->运算符)。

但是,让我们再深入一点……

所以构造函数获取一个SistemPornire实例的引用,并用它来初始化sistem_pornire成员的实例Autoturism。换句话说,您使用您在中声明的部分复制构造sistem_pornire对象。SistemPornireSistemPornireCuPreincalziremain

from 的对象main永远不会被调用,也永远不会被使用。

您应该仔细阅读有关切片问题和C++ 中的虚函数调度的信息。

祝你好运!

于 2013-03-12T22:30:48.150 回答
3

编辑

正如@Roddy 指出的那样,在更新的问题中,切片发生在Autoturism构造函数中。

您通过将派生对象分配给基础对象来对对象进行切片。

SistemPornireCuPreincalzire derived = SistemPornireCuPreincalzire();

SistemPornire base = derived; // sliced

您需要通过引用来引用派生类:

SistemPornireCuPreincalzire derived = SistemPornireCuPreincalzire();

SistemPornire& base = derived; // no slicing

看:

于 2013-03-12T22:02:31.817 回答