简体   繁体   English

如何从继承的类中调用函数?

[英]How to call function from inherited class?

I have the code: 我有代码:

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

c.test() says "class A", but how I can call method getString() from class B and not A? c.test()表示“类A”,但是如何从类B而不是类A调用方法getString()?

Thanks! 谢谢!

The problem is, your B object gets sliced when assigned to an A object. 问题是,将您的B对象分配给A对象时会对其进行切片 This is because you assigned by value, not by reference or pointer. 这是因为您是按值分配的,而不是按引用或指针分配的。 Since you declared a like this 既然你宣布a像这样的

A a;

what happens during the assignment a = b is that the actual state of b is copied over into a . 什么分配期间发生a = b是实际状态b被复制到a However, since a is a value object, only the A part of object b is copied, and its "B-ness" is completely lost! 但是,由于a是值对象,因此仅复制对象bA部分,并且其“ B感”完全消失了!

To avoid this, you need to declare a as a pointer type, as suggested by others (a reference would also work, but then you would need to considerably rewrite your example, since you can't assign to references, only initialize them). 为了避免这种情况,你需要声明a作为指针类型,被别人的建议(参考也将工作,但那么你就需要大大重写你的榜样,因为你不能分配给引用,只对它们进行初始化)。 If a is a pointer ( A* ), the assignment a = b makes a point to the object represented by b , which is still a B object, thus you will observe the polymorphic behaviour you expected. 如果a是一个指针( A* ),分配a = b ,使a点由表示的对象b ,这仍然是一个B对象,因而你将你观察预期的多态行为。 However, in this case, you must ensure that b stays alive even after exiting the constructor - otherwise you leave a dangling reference which causes undefined behaviour (read: bad things you don't want to happen) when dereferenced. 但是,在这种情况下,即使退出退出构造函数后,也必须确保b保持活动状态-否则,您将留下一个悬空的引用 ,该引用在取消引用时会导致未定义的行为 (阅读:您不想发生的不良事情)。

Since a pointer example was already shown by @Nawaz, I will give another using a reference: 由于@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;
};

You need to implement like this: 您需要这样实现:

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

This will call getString() from class B and not A. 这将从类B而不是A调用getString()

What you're trying to do is called "dynamic polymorphism" which is achieved through pointer (or reference ) of type base class (which is A ), but the pointer points to an object of type derived class (which is B ). 您试图做的事情叫做“动态多态性”,它是通过基类(即A )的指针 (或引用 )实现的,但是指针指向类型派生类(即B )的对象。

Because your member a is not an A* , it is an A instance. 因为您的成员a不是A* ,所以它是A实例。 Therefore you are just assigning the A part of B to variable a . 因此,您只是将BA部分分配给变量a if you convert a to an A* , you will get the expected result. 如果将a转换为A* ,将会得到预期的结果。

You are slicing therefore it will not work. 您正在切片,因此将无法使用。 a is an A it is not a B . aA而不是B

To work your class member variable a must be a pointer or a reference. 要使用您的类成员变量,必须是一个指针或引用。

As a pointer 作为指针

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

As a reference 作为参考

class C{
    public:
        C() : a( *(new B) )
        {
        }
        std::string test() {return a.getString();}
    private:
        A &a;
    };

Of course the code I have produced leaks but will work with the virtual function. 当然,我产生的代码会泄漏,但可以与虚函数一起使用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM