以下案例指出了切片问题: 在任务期间: https://stackoverflow.com/a/274634/640639
在函数调用期间: What is object slicing?
我的问题是,如果赋值运算符和复制构造函数被声明为虚拟并且派生类适当地复制所需数据,那么这两种情况都不会得到解决吗?如果原则上按值传递仍然适用于这些情况,是否正确?
答案 0 :(得分:4)
没有。参数由value传递,因此创建了一个新的基础对象。
没有虚构造函数,因为virtual
表示“取决于this
的动态类型”,并且在构造函数运行之前,该对象甚至不存在,所以它不能有派生的动态类型。
虚拟赋值运算符也无济于事,因为它们取决于所分配对象的类型,而不是所分配对象的类型。
如果您希望能够按值复制但仍具有多态行为,则可以创建一个包含指向另一个对象的指针的对象,并在其构造函数和赋值运算符中克隆该对象(使用类似{{3来自Martinho Fernandes'Wheels图书馆):
class Base {
public:
virtual Base* clone() const = 0;
virtual void do_stuff() = 0;
};
class CopyablePolymorphic {
public:
CopyablePolymorphic(Base* base) : ptr(base) {}
private:
value_ptr<Base> ptr;
};
class Derived1 : public Base {
public:
virtual Base* clone() const {
return new Derived1(*this);
}
virtual void do_stuff() {
//Derived1 stuff
}
};
class Derived2 : public Base {
public:
virtual Base* clone() const {
return new Derived2(*this);
}
virtual void do_stuff() {
//Derived2 stuff
}
};
//etc...
答案 1 :(得分:0)
显然,你不能将复制构造声明为virtual
:还没有对象。但是,您可以禁用复制构造。
也就是说,使赋值virtual
仍然不起作用,因为在对对象进行切片时,所分配对象的静态类型仍然只是一个基类。它永远不会成为派生类,而与您分配给它的类型无关。