lez*_*lon 7 c++ object-slicing
可能重复:
虚函数对象切片
让我们考虑一下:
#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
}
Run Code Online (Sandbox Code Playgroud)
哪个功能会被调用?如果不存在切片,基本上可以使用不带指针的多态性吗?
Man*_*Way 13
不,没有指针就不可能.
由于您创建了一个对象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();
}
Run Code Online (Sandbox Code Playgroud)
输出将是:
Hello A
Run Code Online (Sandbox Code Playgroud)
问题是在你的例子中实际上有切片.使用push_back在某种程度上相当于:
A array[N];
array[last++] = B();
Run Code Online (Sandbox Code Playgroud)
在第二行是切片的位置,因为数组中的每个位置都可以从类型中保存一个对象,A但不能从类型中保存一个对象B.
您可以使用指针来解决此问题,定义v为std::vector<A*> v.可能更好,您可以使用智能指针(C++ 11中的指针或Boost中的指针).
多态在没有指针/引用的情况下在C++中工作吗?
是的,不是.
当指针或引用的静态类型可能与它引用的对象的动态类型不同时,动态多态在C++中起作用,并且基于动态类型选择行为.这需要指针或引用,因为对象本身只有一种类型.
静态多态,使用模板,与对象完美协作,但解决了不同类别的问题.您的示例需要动态多态,以根据对象的运行时类型选择行为.
哪个功能会被调用?
向量包含类型的对象A,因此A::do_it()将被调用.该对象不知道它是通过切片类型的对象创建的B.
如果不存在切片,基本上可以使用不带指针的多态性吗?
从派生类对象创建基类对象时,始终存在切片.这就是切片的定义.