根据标准:
如果不是用户提供的,并且如果
,则类X的复制/移动构造函数是微不足道的- 类X没有虚函数(10.3),没有虚基类(10.1)和
- 选择复制/移动每个直接基类子对象的构造函数是微不足道的,
- 对于类型(或其数组)的X的每个非静态数据成员,构造函数 选择复制/移动该成员是微不足道的;
否则复制/移动构造函数不重要。
我认为该标准引入了概念" trival cp / mv ctor"推断你可以使用std :: memcpy而不是调用构造函数来复制类,并且没有未定义的行为。
然而,该标准并不允许虚拟功能的存在,我认为这违反了&t 34 / t 34 / trv ctor / m 34的精神。具有指向虚函数的vtable的类仍然可以使用std :: memcpy复制并具有正确的行为。毕竟,您无法在运行时更改类的vtable - 这将破坏此类的其他实例。
那么,为什么没有用户提供cp / mv ctor且具有虚拟功能但没有虚拟基础的类具有" trival cp / mv ctor"?
答案 0 :(得分:3)
这不是一个微不足道的类型,因为确保“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指向derived
的vtable。所以现在我们获得了一个vtpr指向错误vtable的对象。我们称之为覆盖函数。
轰!
答案 1 :(得分:1)
考虑一个简单的例子:
#include <iostream>
struct ConcreteBase {
virtual void method() {
std::cout << "Basic implementation" << std::endl;
}
};
struct Derived: ConcreteBase {
Derived(int x): extraState{x} {}
void method() {
std::cout << "Overridden (" << extraState << ')' << std::endl;
}
private:
const int extraState;
};
int main() {
ConcreteBase const &b = Derived(42);
ConcreteBase b1{b};
b1.method();
}
你究竟如何使用memcpy来复制vtable? (更广泛地说,你如何轻视ConcreteBase的复制?)