The default copy constructor is member-by-member, not bitwise.
Most CObject-derived classes contain - and manage directly - some system resources, that have no reference counting or similar mechanism, so the choice was probably made with the default use case in mind.
e.g. CGDIObject is roughly:
class CGDIObject : public CObject
{
HGDIOBJ m_handle;
CGDIObject() : m_handle(0) {}
// derived classes provide a create, attach etc.
~CGDIObject() { DeleteObject(m_handle); }
}
The default copy constructor here would be dangerous (leading to double destruction), providing a "correct" copy constructor is surprisingly hard and expensive.
Another reason may be that most CObject-derived classes are intended to be mutated, and thus passed by reference. A missing copy constructor will catch unintended copies that mutate a copy rather than the object passed:
class CMyObject : public CObject
{
public:
AttachFoo(FooHandle foo) { ... }
AddBar() { ... }
};
bool InitMySession(CMyObject & obj)
{
obj.AttachFoo(CreateRawFoo());
obj.AddBar();
obj.AddBar();
}
// ...
CMyObj mo;
InitMySession(mo);
Omitting the "&" gives you code that compiles well, but creates a temporary copy, modifies that, and then drops it, while mo remains unmodified.
Quite many API's follow that pattern, as MFC doesn't rely on exceptions for error handling (for historic reasons: not all targeted compilers did support them well, and MFC requires a lot of extra resource handling that becomes painful with exceptions).
I don't think these choices are good, e.g. derived classes should be allowed to use the default copy constructor if their members permit (and most members should permit).
The decision fits the "mindset" of MFC, though, and the requriements / restrictions of the time MFC was created.