如何从继承类调用函数?

Vex*_*toR 1 c++ class

我有代码:

class A{ //base class
public:
    virtual std::string getString(){return "class A";}
};

class B: public A{
public:
    std::string getString() {return "it is B class";}
};

class C{
public:
    C(){
        B b;
        a = b;
    }
    std::string test() {return a.getString();}
private:
    A a;
};


int main()
{
    C c;
    std::cout << c.test();

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

c.test()说"A类",但我如何从B类调用方法getString()而不是A?

谢谢!

Pét*_*rök 7

问题是,在分配给对象时,B对象会被切片A.这是因为您按值分配,而不是通过引用或指针分配.既然你a这样说了

A a;
Run Code Online (Sandbox Code Playgroud)

在赋值期间发生的事情a = b是将实际状态b复制到a.但是,由于a是一个值对象,只复制A了对象的一部分b,并且它的"B-ness"完全丢失了!

为了避免这种情况,你需要a像其他人所建议的那样声明为指针类型(引用也可以工作,但是你需要大量重写你的例子,因为你不能分配引用,只能初始化它们).如果a是一个指针(A*),分配a = b使a点所代表的对象b,这仍然是一个B对象,所以你会看到你所期望的多态行为.但是,在这种情况下,您必须确保b即使在退出构造函数后仍保持活动状态 - 否则您会在取消引用时留下一个悬空引用,该引用会导致未定义的行为(读取:您不希望发生的不良事件).

由于@Nawaz已经显示了一个指针示例,我将使用引用给另一个:

class C{
public:
    C() : a(b) { // references must be initialized in the constructor initializer list
    }
    std::string test() {return a.getString();}
private:
    B b; // moved to class scope to ensure that it stays alive
    A& a;
};
Run Code Online (Sandbox Code Playgroud)


Naw*_*waz 5

你需要像这样实现:

class C{
public:
    C(){
        a = new B;
    }
    std::string test() {return a->getString();}
private:
    A *a;
};
Run Code Online (Sandbox Code Playgroud)

这将从getString()B级调用,而不是A.

你想要做的是被称为"动态多态",它是通过类型基类(即)的指针(或引用)实现的A,但指针指向派生类类型的对象(即B).