Bai*_*ang 8 c++ mfc constructor
默认情况下禁用MFC的根对象CObject的复制构造函数和赋值.
标准C++默认类复制构造函数执行成员复制.如果需要类的复制构造函数但不可用,则私有CObject复制构造函数的存在可保证编译器错误消息.因此,如果您的类需要此功能,则必须提供复制构造函数.
默认情况下禁用复制构造函数和赋值,因此如果按值传递对象或分配对象,则会出现编译器错误而不是意外行为.
我的问题是,这个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); }
}
Run Code Online (Sandbox Code Playgroud)
这里的默认复制构造函数是危险的(导致双重破坏),提供"正确"的复制构造函数是非常困难和昂贵的.
另一个原因可能是大多数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);
Run Code Online (Sandbox Code Playgroud)
省略"&"会为您提供编译良好的代码,但会创建一个临时副本,修改它,然后删除它,同时mo保持不变.
很多API遵循这种模式,因为MFC不依赖于错误处理的异常(出于历史原因:并非所有目标编译器都支持它们,并且MFC需要大量额外的资源处理,这会因异常而变得痛苦).
我不认为这些选择是好的,例如,如果成员允许(并且大多数成员应该允许),则应允许派生类使用默认的复制构造函数.
然而,该决定符合MFC的"思维模式",以及MFC创建时间的要求/限制.