2

I won't write all the code, but I am looking at a smart pointer example implementation and it has:

template<typename T>
class smart_ptr
{

public:
    operator void*() const {return mPtr;}

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

    const T* operator->() const;
    T* operator->();

private:
    T* mPtr;
};
  1. What is the purpose of the first public function in the API?
  2. Why do we need to const-overload the other two API methods?
  3. Not only const-overload, but why have return-const-object variants?
user997112
  • 29,025
  • 43
  • 182
  • 361
  • 1
    The `operator*` and `operator->` functions don't appear to be overloaded, so it's not clear what you mean about const-overloading them. They're `const` because they don't modify the smart pointer object. – Wyzard Mar 23 '14 at 01:37
  • 1. That's an [implicit conversion operator](http://stackoverflow.com/a/16615725/1139697). It enables you to use a `smart_ptr` whenever you would usually use a `void *`. Handle with care. – Zeta Mar 23 '14 at 01:38
  • May be this article provides some enlightment for you: [Smart Pointers in C++](http://www.informit.com/articles/article.aspx?p=31529). – πάντα ῥεῖ Mar 23 '14 at 01:51
  • @Wyzard do you mean they aren't overloaded because the return type differs? If they had all returned a const object, then they would have been const-overloaded? – user997112 Mar 23 '14 at 02:19
  • It's not that the return type differs, it's that the *name* differs. Overloading is when you have multiple functions with the same name but different signature. The `operator*` and `operator->` functions have different names, so they're not overloads of each other. – Wyzard Mar 23 '14 at 02:38

2 Answers2

1

The conversion operator looks to be intended to do two things:

  1. Convert the smart pointer to void*. Generally pointers convert to void* but I'm not sure whether it is a good idea to do for smart pointers.
  2. It will be used when testing objects to see what value they have when evaluated in a boolean context. That can be used to determine if the pointer is a null pointer.

Personally, I would probably only support the second use-case and use an explicit conversion to bool instead:

explicit operator bool() const { return this->mPtr; }

The overloads for const are obviously intended to propagate constness of the smart pointer to the pointed to objects.

Dietmar Kühl
  • 150,225
  • 13
  • 225
  • 380
1

The operator void* function is a type casting function, so you can write:

smart_ptr foo;
void* ptr = foo;  // The compiler will call `operator void*` here

or even

if( foo) {  // `operator void*` called to test boolean expression
  //...
}

The functions

const T& operator*() const;

const T* operator->() const;

are const, so you can call them on a const smart_ptr. Because they return pointer/reference to const object, this object can't be changed.

4pie0
  • 29,204
  • 9
  • 82
  • 118
  • Regarding Q2/3 why couldnt the non-const methods also return a const object? A method's const-ness is unrelated to whether the return object is const or not? – user997112 Mar 23 '14 at 01:52
  • yes these are two different things. Function const can be called on const object, this is why these are const functtions – 4pie0 Mar 23 '14 at 01:58
  • What is the purpose of returning the const objects? I see the reasoning for providing const methods (operating on const smart pointers). – user997112 Mar 23 '14 at 02:18
  • Why return a void*? Wouldn't `operator T*() const {return mPtr;}` make more sense as it allows for code `T* rawPointer = smartPointer; // smartPointer is of type smart_ptr`, while the void* variant does not? – Kaiserludi Nov 30 '16 at 18:02
  • Correct, operator T*() const {return mPtr;} would be preferred for this case. This is not the only thing that can be improved in this class though. – 4pie0 Dec 02 '16 at 01:36