多态性在没有指针/引用的C++中工作吗

Does polymorphism work in C++ without pointers / references?

本文关键字:C++ 工作 引用 指针 多态性      更新时间:2023-10-16

可能重复:
虚拟函数对象切片

让我们考虑一下:

#include <vector>
#include <iostream>
using namespace std;
struct A {
    virtual void do_it() { cout << "A" << endl; } 
};
struct B : public A {
    virtual void do_it()  { cout << "B" << endl; } 
};
int main() {
    vector<A> v;
    v.push_back(B());
    v[0].do_it(); // output is A
}

将调用哪个函数?如果不存在切片,基本上可以在没有指针的情况下使用多态性吗?

不,没有指针是不可能的。

由于您创建了一个对象B并将其推送到包含A的向量中,它将被复制(发送到A的复制构造函数),并且A的实例将被添加到向量中。也就是说,物体将被切开。

给定此代码:

struct A {
        virtual void d() { 
            std::cout << "Hello A" << std::endl; 
        } 
};
struct B : public A {
        virtual void d() { 
            std::cout << "Hello B" << std::endl; 
        } 
};
int main() {
        std::vector<A> v;
        v.push_back(B());
        v[0].d();
}

输出为:

Hello A

问题是在您的示例中实际上存在切片。使用push_back在某种程度上等同于:

A array[N];
array[last++] = B();

第二行是进行切片的位置,因为数组中的每个位置都可以容纳类型为A的对象,但不能容纳类型为B的对象。

您可以使用指针来解决这个问题,将v定义为std::vector<A*> v。也许更好的是,你可以使用智能指针(要么是C++11中的指针,要么是Boost中的指针)。

多态性在没有指针/引用的C++中工作吗?

是和否

当指针或引用的静态类型可能与其引用的对象的Dynamic类型态多态性在C++中起作用。这需要指针或引用,因为对象本身只有一种类型。

Static多态性使用模板,可以完美地处理对象,但解决了另一类问题。您的示例需要动态多态性,以便根据对象的运行时类型来选择行为。

将调用哪个函数?

矢量包含类型为A的对象,因此将调用A::do_it()。该对象不知道它是通过对类型为B的对象进行切片而创建的。

如果不存在切片,基本上可以在没有指针的情况下使用多态性吗?

从派生类对象创建基类对象时,切片始终存在。这就是切片的定义。

多态性在没有指针/引用的C++中工作吗?

是的。请参阅静态多态性

在您的情况下,将调用基函数,但说多态性不起作用是错误的。多态性是有保证的,只是你没有利用它。你所拥有的基本上是一个a对象的集合。

这将不起作用,因为sizeof(父级)并不总是等于sizeof(子级)