0

Consider this code

// Example program
#include <iostream>
#include <string>

class SmartPtr{
    int *ptr;
    public:
    explicit SmartPtr(int *ptr=0){
        ptr = new int;
    }
    ~SmartPtr(){
        std::cout<<"Dest is called"<<std::endl;}
    int& operator *()   //overloaded operator for dereferencing 
    {
    std::cout<<"(*) is called .."<<std::endl;
    return *ptr;
    }

    int * operator ->()  //overloaded operator for referencing 
    { 
        std::cout<<"(*) is called .."<<std::endl;
        return ptr;
        }
};

int main()
{

    SmartPtr p(new int());
    *p = 20;   //overloaded operator * called
    std::cout<<*p<<std::endl;   // Overloaded operator * called
    // End of program 
    //Destructor called 

}

here i have overloaded operators * and & , i want to understand why that type of function signature based on the comments i have mentioned in main function . If someone can explain how it works ?

PS : I am new to C++ and explaination i am asking is trivial {i know :)}

del_champ
  • 179
  • 1
  • 9
  • "here i have overloaded operators * and &" - wait, *you* overloaded these operators, but don't know how the code *you* wrote works? – WhozCraig Sep 11 '16 at 07:06
  • Its a copied code @WhozCraig i want to understand this code in a way i can implement something like this on my own – del_champ Sep 11 '16 at 07:08
  • Apparently unrelated to your question then, probably the biggest problem with this code is the lack of actually initializing, or assigning, `ptr`, the member variable, in that constructor. `ptr = ...` in the constructor is modifying the parameter automatic variable; the *member* `ptr` remains default-initialized (to indeterminate value). When done, `p.ptr` in `main` remains indeterminate, and both `new int` are leaked., Thus alter when you dereference it with your `operator *` and attempt to store a value therein you invoke *undefined behavior*. – WhozCraig Sep 11 '16 at 07:27
  • Also has a memory leak because the destructor doesn't clean up. Fixing the leak will expose a [Rule of Three problem.](http://stackoverflow.com/questions/4172722/what-is-the-rule-of-three) – user4581301 Sep 11 '16 at 07:52
  • Clarify please: Do you know what the `*` and `->` operators do in the general case? If not [give this a read.](http://en.cppreference.com/w/cpp/language/operator_member_access) It may answer your question. – user4581301 Sep 11 '16 at 07:55

2 Answers2

1

This is the way smart pointers are constructed. They are wrappers of pointers of any class and they control the deallocation of these objects by automatically calling their destructor when the smart pointer goes out of scope. In order to expose the interface of the wrapped class, they must overload * and -> operators and return the wrapped object's pointer.

GeorgeT
  • 484
  • 3
  • 5
1

In C++ you can define functions as behavior of operators on your types. That is exactly, what happens here.

int& operator * () declares the function, that is used for the unary * operator. The result of that operator then is a reference to an int.

int* operator -> ()then declares the function for ->. This one is a bit special, since it will be used on the return value again, until there is a pointer, which will be used to apply the standard behavior of ->.

After you have declared these operators, the compiler will accept them on any object of your type. You can then write *myObj go get the result of the operator * () function.

This feature gives you the power to extend the language in parts. Note, that the return types can be chosen as needed. If you look at advanced libraries, that implement domain specific languages, you'll find a lot of that. Boost::spirit is an extreme example of that.

cdonat
  • 2,748
  • 16
  • 24