简体   繁体   English

误解了虚函数在矢量中的作用

[英]Misunderstood the virtual functions work in vector

I have following code on c++: 我在c ++上有以下代码:

#include <iostream>;
#include <vector>;

class A
{
public:
    A(int n = 0) : m_n(n) { }

public:
    virtual int value() const { return m_n; }
    virtual ~A() { }

protected:
    int m_n;
};

class B
    : public A
{
public:
    B(int n = 0) : A(n) { }

public:
    virtual int value() const { return m_n + 1; }
};

int main()
{
    const A a(1);
    const B b(3);
    const A *x[2] = { &a, &b };
    typedef std::vector<A> V;
    V y;
    y.push_back(a);
    y.push_back(b);
    V::const_iterator i = y.begin();

    std::cout << x[0]->value() << x[1]->value()
        << i->value() << (i + 1)->value() << std::endl;

    system("PAUSE");

    return 0;
}

The compiler returned result: 1413. 编译器返回结果:1413。

I am little bit confused, because I thought the right result would be 1414 (as the function virtual). 我有点困惑,因为我认为正确的结果将是1414(作为虚拟函数)。 How do you explain this program behavior? 您如何解释该程序的行为?

You are slicing the object, in order to get polymorphism you need to use either a pointer or a reference . 您正在切片对象,为了获得多态性,您需要使用pointerreference This example keeping as close as possible to your original example and using a pointer will act as you wanted: 该示例尽可能接近您的原始示例并使用pointer将按照您的意愿进行操作:

const A a(1);
const B b(3);

typedef std::vector<const A*> V;
V y;
y.push_back(&a);
y.push_back(&b);
V::iterator i = y.begin();

std::cout << (*i)->value()  << std::endl ;
++i ;
std::cout << (*i)->value()  << std::endl ;

To show briefly how the object slicing works here: 要在此处简要显示对象切片的工作方式:

const A a(1);
const B b(3);
std::vector<A> y; // so y contains objects of type A

y.push_back(a);   // y[0] is copy-constructed from a
y.push_back(b);   // y[1] is copy-constructed from b

Note that in both push_back calls, it's always an A being constructed, via the automatically-generated A::A(const A&) copy constructor. 注意在这两个push_back调用,它总是一个A正在建设中,通过自动生成的A::A(const A&)拷贝构造函数。

Note also that a B is-a A , which is to say b can be implicitly cast to an A and passed into the same copy-constructor. 还要注意, B A ,也就是说b可以隐式转换为A并传递到相同的复制构造函数中。

So, y[1] is an instance of A with the m_n value copied from b , but its virtual function is still A::value . 因此, y[1]A一个实例,具有从b复制的m_n值,但其虚函数仍然是A::value If you have constructor B::B modify the value when it is initialized, instead of when it is returned, you'll see the result you expect. 如果您具有构造函数B::B ,则在初始化时(而不是在返回时)修改值,您将看到预期的结果。

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

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