Solved

Handle class and dereferencing operator

Posted on 2014-01-13
5
409 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 34

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 34

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

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

What is C++ STL?: STL stands for Standard Template Library and is a part of standard C++ libraries. It contains many useful data structures (containers) and algorithms, which can spare you a lot of the time. Today we will look at the STL Vector. …
This article will show you some of the more useful Standard Template Library (STL) algorithms through the use of working examples.  You will learn about how these algorithms fit into the STL architecture, how they work with STL containers, and why t…
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

749 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