一般に問題は、オブジェクトがデータだけでなく動作も導入することです。
データを手動でコピーすると、コピー コンストラクターに依存している可能性があるオブジェクトの固有の動作が壊れる可能性があります。
良い例は、共有または一意のポインターです。それをコピーすると、そのクラスを使用したときにそのクラスで行った「取引」が破棄されます。
コピー プロセスが意味的に正しいかどうかに関係なく、その背後にある考え方は間違っており、オブジェクト プログラミングのパラダイムに違反しています。
サンプルコード:
/** a simple object wrapper around a pthread_mutex
*/
class PThreadMutex
{
public:
/** locks the mutex. Will block if mutex is already locked */
void lock();
/** unlocks the mutex. undefined behavior if mutex is unlocked */
void unlock();
private:
pthread_mutex_t m_mutex;
};
/** a simple implementation of scoped mutex lock. Acquires and locks a Mutex on creation,
* unlocks on destruction
*/
class ScopedLock
{
public:
/** constructor specifying the mutex object pointer to lock
* Locks immediately or blocks until lock is free and then locks
* @param mutex the mutex pointer to lock
*/
ScopedLock ( PThreadMutex* mutex );
/** default destructor. Unlocks the mutex */
~ScopedLock ();
/** locks the mutex. Will block if mutex is already locked */
void unlock();
private:
PThreadMutex* m_mutex;
// flag to determine whether the mutex is locked
bool m_locked;
// private copy constructor - disable copying
ScopedLock(ScopedLock &mutex) { (void)mutex; /* to get rid of warning */ };
};
クラスをコピーScopedLock
し、手動でロックを解除してから値を復元し、コンストラクターで別のロック解除を実行すると、未定義の動作が発生します (または、少なくともデストラクタで EPERM エラーが発生します)。