[英]Why do classes with no user-provide cp/mv ctor and have virtual functions but no virtual bases not have “trival cp/mv ctor”?
根据标准:
如果类X的复制/移动构造函数不是由用户提供的,并且不是
—类X没有虚拟函数(10.3)和虚拟基类(10.1),并且
—选择复制/移动每个直接基类子对象的构造函数很简单,并且
—对于类类型(或其数组)的X的每个非静态数据成员,选择用来复制/移动该成员的构造函数都是微不足道的;
否则,复制/移动构造函数是不平凡的。
我认为该标准引入了概念“ 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指向derived
的vtable。 因此,现在我们获得了一个对象,其vtpr指向错误的vtable。 我们称为覆盖函数。
繁荣!
考虑一个简单的例子:
#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的复制ctor?)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.