Solved

Handle class and dereferencing operator

Posted on 2014-01-13
5
404 Views
Last Modified: 2014-01-13
I have the following Handle (smart pointer) class, written as an exercise.

template <class T> class Handle
{
public:
	Handle() : p(0) { }
	Handle(T* t) : p(t)	{ }
	// copy constructor
	Handle(const Handle& h) : p(0)
	{
		if (h.p) // check if the handle points to something, otherwise there is nothing to clone
			p = h.p->clone();  // T must have a clone() method.
	}
	Handle& operator=(const Handle&); // assignment operator
	~Handle() { delete p; }
	// need to use comparison with NULL in order to avoid warning in VS 2010 and above
	operator bool() const { return (p != NULL); } // conversion operator from Handle to bool. Uses implicit conversion from pointer to bool
	T& operator*() const;
	T* operator->() const;
private:
	T* p;
};

Open in new window

The class appears to work perfectly fine. However, I have noticed that some books suggest that the * and -> operators should be overloaded in both const and non-const versions, e.g.

T& operator*();
const T& operator*() const

Open in new window

What is the advantage of doing that (if any)?
0
Comment
Question by:Rothbard
  • 2
  • 2
5 Comments
 
LVL 32

Expert Comment

by:sarabande
ID: 39776618
if using the following function

int f(Handle<int> & hx, const Handle<int> &hcx)
{
      int &  x = *hx;  
      const int &  cx = *hcx;  

      return 1111 + cx + x;
}

Open in new window


the first dereference expression would use the T& operator* while the second would use the const T& operator*. if both have the same implementation, it makes no difference, but you could use a different implementation, for example return a reference to a const static member if the pointer is 0 in the const operator while you throw an exception in the non-const operator.

Sara
0
 

Author Comment

by:Rothbard
ID: 39776645
Thanks for your comment. In my Handle class above, the * operator is implemented as follows

template <class T> T& Handle<T>::operator*() const
{
	if (p)
		return *p;
	else
		throw runtime_error("Attempting to dereference unbound Handle.");
}

Open in new window

I can see that your code for the f function runs fine with my definition of *, so I am still not sure why two separate versions are needed. The fact that the method operator*() is const allows it to work on const Handle objects, but it works equally well with non-const objects.
0
 
LVL 32

Assisted Solution

by:sarabande
sarabande earned 100 total points
ID: 39776679
I used the following implementation:

T& operator*()  
 { 
      return *p; 
 }
 const T& operator*() const 
 { 
      return *p; 
 }

Open in new window


and could see that the compiler used a different operator depending on the constness of the variables and arguments. because of that you could have a different implementation for read-only operations what might be useful sometimes.

Sara
0
 
LVL 40

Accepted Solution

by:
evilrix earned 250 total points
ID: 39776774
It's only necessary to implement a const operator. There is no need to implement a non-const operator because constness of the smart pointer container does not reflect constness of the pointer it is managing.

The C++11 standard shared pointer only implements const operators, both return pointers to type T. T will define what the characteristics are of the pointer being managed. In other words T may or may not be const.

http://en.cppreference.com/w/cpp/memory/shared_ptr/operator*
0
 

Author Closing Comment

by:Rothbard
ID: 39776876
Thanks!
0

Featured Post

Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

Join & Write a Comment

When writing generic code, using template meta-programming techniques, it is sometimes useful to know if a type is convertible to another type. A good example of when this might be is if you are writing diagnostic instrumentation for code to generat…
Introduction This article is the first in a series of articles about the C/C++ Visual Studio Express debugger.  It provides a quick start guide in using the debugger. Part 2 focuses on additional topics in breakpoints.  Lastly, Part 3 focuses on th…
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.

706 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now