nnrales nnrales - 16 days ago 8
C++ Question

Why isn't operator* calling constructor ?

Hi please take a look at this.

struct obj
{
std::string _name;
int _val;

obj(const std::string& name_ , int val_) : _name(name_) , _val(val_)
{
std::cout << "Created - " << std::endl;
}

~obj()
{
std::cout << "Deleted - " << std::endl;
}

obj operator *(const obj& obj_) const
{
return obj(_name , obj_._val * _val);
}


friend std::ostream& operator<< (std::ostream& out_, const obj& obj_)
{
out_ << " Name = " << obj_._name << " | val = " << obj_._val << std::endl;
return out_;
}
};

template <typename T>
T square(T x)
{
return x*x;
}


int main()
{
obj a("a" , 5);
std::cout << square(a);
}


The output when I run this is :

Created -
Created -
Name = a | val = 25
Deleted -
Deleted -
Deleted -


I am wondering why there is a unbalanced number of creation and destruction ? I suspect that a temporary object is being created when the operator* is called, but shouldn't the temporary object call the constructor too? I can balance it if I put a std::cout << "created" with in operator*.

I am just wondering why operator* does not call the contructor as I am clearly creating a temporary object there ? Does the templates have anything to do with this? I don't think so. Any help in understanding what I am doing wrong will be great !

Answer

You forgot to output when the copy constructor is invoked. Since obj is being returned by value in operator *, copies can occur (they can be elided by the compiler, but let's assume they're not).

obj(const obj& rhs) : _name(rhs._name), _val(rhs._val)
{
   std::cout << "copy constructor called" << std::endl;
}

This should give you a better picture of what's going on when you return obj by value.