默认禁用MFC根对象CObject的拷贝构造函数和赋值。
- 在 MSDN 中,有一个 description
The standard C++ default class copy constructor does a member-by-member copy. The presence of the private CObject copy constructor guarantees a compiler error message if the copy constructor of your class is needed but not available. You must therefore provide a copy constructor if your class requires this capability.
- 在CObject的源码中,有一句注释:
Disable the copy constructor and assignment by default so you will get compiler errors instead of unexpected behaviour if you pass objects by value or assign objects.
我的问题是,这个 CObject 类的默认逐位复制构造函数有什么问题?在我看来,最好给我们一个默认的复制构造函数,如果需要的话我们可以提供一个(深复制)
最佳答案
默认的复制构造函数是逐个成员的,而不是按位的。
大多数 CObject 派生类包含 - 并直接管理 - 一些没有引用计数或类似机制的系统资源,因此做出选择时可能考虑了默认用例。
例如CGDIObject 大致是:
class CGDIObject : public CObject
{
HGDIOBJ m_handle;
CGDIObject() : m_handle(0) {}
// derived classes provide a create, attach etc.
~CGDIObject() { DeleteObject(m_handle); }
}
此处的默认复制构造函数是危险的(导致双重破坏),提供“正确”的复制构造函数出奇地困难且昂贵。
另一个原因可能是大多数 CObject 派生类都旨在进行变异,因此通过引用传递。缺少的复制构造函数将捕获意外的拷贝,这些拷贝会改变拷贝而不是传递的对象:
class CMyObject : public CObject
{
public:
AttachFoo(FooHandle foo) { ... }
AddBar() { ... }
};
bool InitMySession(CMyObject & obj)
{
obj.AttachFoo(CreateRawFoo());
obj.AddBar();
obj.AddBar();
}
// ...
CMyObj mo;
InitMySession(mo);
省略“&”会让你的代码编译得很好,但会创建一个临时拷贝,修改它,然后删除它,而 mo
保持不变。
很多 API 都遵循这种模式,因为 MFC 不依赖异常进行错误处理(由于历史原因:并非所有目标编译器都很好地支持它们,并且 MFC 需要大量额外的资源处理,异常会变得很痛苦) .
我认为这些选择都不好,例如如果派生类的成员允许(并且大多数成员应该允许),应该允许派生类使用默认的复制构造函数。
不过,该决定符合 MFC 的“思维模式”,以及创建 MFC 时的要求/限制。
关于c++ - 为什么禁用 CObject 的复制构造函数和赋值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3085257/