指定对不可复制的派生对象进行混叠的基础引用
Assignment of base references aliasing non copyable derived objects
我与一位同事讨论了将抽象基类标记为不可复制的必要性。我认为没有必要这样做,因为基类是抽象的,因此我们不能有基类的实例,所以通过基类引用进行复制不是问题。派生类可以自己决定是否允许复制。然而,我的同事给我看了一个基本参考文献的分配案例,这让我有点惊讶。
#include <stdio.h>
struct B
{
virtual void foo() = 0;
virtual ~B(){}
};
struct D : public B
{
D(int i): data(i){}
void foo() override {printf("%d", data);}
int data;
D& operator=(D) = delete;
D(const D&) = delete;
};
int main()
{
D d(1);
D d2(2);
d.foo();
d2.foo();
B& b = d;
B& b2 = d2;
b.foo();
b2.foo();
b = b2; // what is this doing?
b.foo();
b2.foo();
d.foo();
d2.foo();
}
上面的代码输出:12121212
。我真的不明白这里发生了什么。b = b2;
做什么?我预料到这里会出现编译错误。
您没有定义复制赋值运算符,因此会默认使用一个。
默认的不是virtual
,所以它会将d2
的B
子对象的任何成员变量复制到d
的B
子对象。(B::operator=
对D::operator=
一无所知)。
像这样使用基类operator=
在一般情况下确实会破坏封装;尽管在这种情况下,由于B
没有成员变量,也没有基类,所以这一行实际上没有任何作用。
因此,在这里将B
标记为不可编辑可能过于防御性;因为这将强制所做想要可复制的任何子类跳过重重关卡以重新启用复制。
相关文章:
- 引用对象成员函数的成员函数
- 从 Base 引用对象调用派生类的成员
- 转换引用对象的边界框?
- 现代编译器会优化只引用对象子集的局部变量吗
- l值引用对象上的Constexpr成员函数:Clang和gcc不同意
- 将 const 类型引用对象注册为类成员对象C++
- Boost Intervocess:通过迭代通过从结构引用对象的映射进行迭代时
- 无法用2D矢量成员引用对象
- 在由引用对象传递中访问由引用对象传递的变量
- 如何使用QString引用对象名称
- 使用自动迭代器引用对象
- C++ 在另一个对象中引用对象的当前状态
- 使用共享对象和引用对象进行引用计数
- 未显式引用对象的全局对象构造函数在最终二进制文件 - LD 中被丢弃
- 引用对象的动态类型何时可以更改
- 引用对象内部的指针
- C++从全局静态函数中引用对象
- C++如何仅在没有其他人直接或间接引用对象指针时删除该指针
- 如何使用C++引用对象
- 为什么引用对象仅保存特定类型的引用