Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Disallowing creation of the temporary objects

Tags:

c++

temporary

mfc

While debugging crash in a multithreaded application I finally located the problem in this statement:

CSingleLock(&m_criticalSection, TRUE); 

Notice that it is creating an unnamed object of CSingleLock class and hence the critical section object gets unlocked immediately after this statement. This is obviously not what the coder wanted. This error was caused by a simple typing mistake. My question is, is there someway I can prevent the temporary object of a class being created at the compile time itself i.e. the above type of code should generate a compiler error. In general, I think whenever a class tries to do some sort of resource acquisition then the temporary object of that class should not be allowed. Is there any way to enforce it?

like image 573
Naveen Avatar asked May 27 '09 09:05

Naveen


People also ask

Is temporary object created in return by reference?

Explanation: The temporary object is not created. If object is returned by reference, a particular memory location will be denoted with another name and hence same address values will be used.

What is a temporary object in Java?

Temporary objects are those that have a short lifetime and generally serve no useful purpose other than to act as containers for other data. Programmers generally use temporary objects to pass compound data to -- or return it from -- a method.


1 Answers

Edit: As j_random_hacker notes, it is possible to force the user to declare a named object in order to take out a lock.

However, even if creation of temporaries was somehow banned for your class, then the user could make a similar mistake:

// take out a lock: if (m_multiThreaded) {     CSingleLock c(&m_criticalSection, TRUE); }  // do other stuff, assuming lock is held 

Ultimately, the user has to understand the impact of a line of code that they write. In this case, they have to know that they're creating an object and they have to know how long it lasts.

Another likely mistake:

 CSingleLock *c = new CSingleLock(&m_criticalSection, TRUE);   // do other stuff, don't call delete on c... 

Which would lead you to ask "Is there any way I can stop the user of my class from allocating it on the heap"? To which the answer would be the same.

In C++0x there will be another way to do all this, by using lambdas. Define a function:

template <class TLock, class TLockedOperation> void WithLock(TLock *lock, const TLockedOperation &op) {     CSingleLock c(lock, TRUE);     op(); } 

That function captures the correct usage of CSingleLock. Now let users do this:

WithLock(&m_criticalSection,  [&] {         // do stuff, lock is held in this context.     }); 

This is much harder for the user to screw up. The syntax looks weird at first, but [&] followed by a code block means "Define a function that takes no args, and if I refer to anything by name and it is the name of something outside (e.g. a local variable in the containing function) let me access it by non-const reference, so I can modify it.)

like image 134
Daniel Earwicker Avatar answered Oct 05 '22 03:10

Daniel Earwicker