根据标准:
A copy/move constructor for class X is trivial if it is not user-provided and if
— class X has no virtual functions (10.3) and no virtual base classes (10.1), and
— the constructor selected to copy/move each direct base class subobject is trivial, and
— for each non-static data member of X that is of class type (or array thereof), the constructor selected to copy/move that member is trivial;
otherwise the copy/move constructor is non-trivial.
我认为该标准引入了“trival cp/mv ctor”的概念来推断您可以使用 std::memcpy 复制类而不是调用构造函数,并且不会有未定义的行为。
但是,该标准不允许虚拟函数的存在,我认为这违背了“trival cp/mv ctor”的精神。具有指向虚函数的 vtable 的类仍然可以使用 std::memcpy 进行复制,并且具有正确的行为。毕竟,您无法在运行时更改类的 vtable —— 这会破坏此类的其他实例。
那么,为什么没有用户提供 cp/mv ctor 且具有虚拟函数但没有虚拟基的类不能具有“trival cp/mv ctor”?
最佳答案
这不是一个简单的类型,因为确保“vptr”指向正确的“vtable”并不像复制指针的值那么简单。我们可以仅复制基本子对象。我们不需要总是处理最派生的对象类型。
void bar(base const& b) {
b.overriden_function();
}
void foo(base const& b) {
auto other_b = b;
bar(other_b);
}
int main() {
derived d;
foo(d);
}
让我们假设base
是微不足道的。这样拷贝就按照你说的完成了。 b
的 vptr 指向 driven
的 vtable。所以现在我们获得了一个对象,其 vtpr 指向错误的 vtable。我们调用一个重写函数。
繁荣!
关于c++ - 为什么没有用户提供 cp/mv ctor 且具有虚拟函数但没有虚拟基的类没有 "trival cp/mv ctor"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49473684/