我们可以在C ++中创建一个类复制构造函数virtual吗?怎么用?
答案 0 :(得分:22)
不,你不能,构造者不能虚拟。
C ++ 03 - 12.1构造函数
4)构造函数不应是
virtual
(10.3)或static
(9.4)。 [...]
如果你需要这样的东西,你可以查找虚拟构造函数习语here。
答案 1 :(得分:4)
不,你不能。
此外,整个概念没有意义。虚函数是根据对象的值(对象的动态类型)调度的函数。当调用构造函数时,该对象还没有值(因为它尚未构造)。因此,不可能发生虚拟调度。
想一想。这样的构造函数有什么语义?
答案 2 :(得分:1)
没有。 C ++是静态类型语言,C ++编译器以多态方式创建对象是没有意义的。编译器必须知道要创建对象的类类型。换句话说,要创建的对象类型是从C ++编译器角度来看的编译时决策。如果我们使构造函数为virtual,则编译器会标记错误。
答案 3 :(得分:1)
您不能因为在根据新类型的大小而不是复制操作数调用构造函数之前分配内存。如果确实有效,那么对于许多语言结构来说,反转多态性将是一种特殊情况。
但这并不意味着它不能用一点C ++魔法来完成。 :)
在某些情况下,它非常有用,比如序列化非POD类。此示例创建一个使用placement new工作的虚拟副本构造函数。
警告:这是一个可以帮助某些用户遇到特定问题的示例。不要在通用代码中执行此操作。如果为新类分配的内存小于派生类,则会崩溃。使用它的最佳(也是唯一)安全方法是管理自己的类内存并使用新的位置。
class VirtualBase
{
public:
VirtualBase() {}
virtual ~VirtualBase() {}
VirtualBase(const VirtualBase& copy)
{
copy.VirtualPlacementCopyConstructor(this);
}
virtual void VirtualPlacementCopyConstructor(void*) const {}
};
class Derived :: public VirtualBase
{
public:
...
Derived(const Derived& copy) : ... don't call baseclass and make an infinite loop
{
}
protected:
void VirtualPlacementCopyConstructor(void* place) const
{
new (place) Derived(*this);
}
};
答案 4 :(得分:0)
从不,在C ++中不可能。
答案 5 :(得分:0)
是的,您可以创建虚拟副本构造函数,但不能创建虚拟副本构造函数。
原因:
虚拟构造函数:-不可能,因为c ++是静态类型语言,并且将构造函数创建为虚拟,因此编译器将由于virtual关键字而无法决定它的对象类型并将整个过程留给运行时。 编译器必须知道创建对象的类类型。换句话说,从C ++编译器的角度来看,要创建哪种类型的对象是编译时的决定。如果我们将构造函数设为虚拟,编译器会标记错误。
虚拟副本构造函数:-是可能的,请考虑剪贴板应用程序。剪贴板可以容纳不同类型的对象,并从现有对象复制对象,然后将其粘贴到应用程序画布上。同样,要复制的对象类型是运行时决策。虚拟副本构造函数填补了这里的空白。