LockFile(const LockFile&) {}
is generated by the compiler if you don't write it. The compiler version does a memberwise copy (calling copy ctors of all embedded objects). Consider this code:
\nclass LockFile\n{\npublic: \n LockFile(int fileId) : _lock(primitiveCreateLockFileFunction(fileId)) {}\n ~LockFile() { primitiveReleaseLock(_lock); }\nprivate: \n int _lock;\n};\n\nfunc(LockFile lock) {}\n....\nLockFile lock(aFileId);\n\nfunc(lock); // object is copied via the copy constructor - at end of function it is destroyed - releasing the lock\n
See the problem? A for the duration of func, there are two copies of the lock object - one passed to func, the other in the calling stack frame. They end up sharing the same lock and your lock gets free'd early. There are two fixes to this
1) Always pass lock by reference.
2) Make FileLock's copy ctor private so the compiler will prevent unintentional copying since you haven't made the object copy safe.
The second method is similar, but used in assignment and once again, the compiler will generate it for you if you don't.
You should always define the "big 4" methods and, if you can't make some of them safe, make them private so nothing can call them.