constructor conversion vs operator =

V

vairavans

Hi Everyone,

I have the following code,

class B
{
};

class A
{
public: A()
{
}
A(B& ref_obj)
{
printf("conversion\n");
}
~A()
{
}
A operator=(const B& ref)
{
printf("operator\n");
return A();
}
};

int main()
{
A obj;
B obj1;
obj = obj1; // invokes the operator=
A obj2 = obj1 // invokes the constructor conversion
obj2 = obj1 // invokes the constructor conversion, when
the operator= function is commented out
return(0);
}

What does the standard say about this? invoking a constructor when the
object on lvalue is already created...
 
O

Ondra Holub

Hi Everyone,

I have the following code,

class B
{

};

class A
{
public: A()
{
}
A(B& ref_obj)
{
printf("conversion\n");
}
~A()
{
}
A operator=(const B& ref)
{
printf("operator\n");
return A();
}

};

int main()
{
A obj;
B obj1;
obj = obj1; // invokes the operator=
A obj2 = obj1 // invokes the constructor conversion
obj2 = obj1 // invokes the constructor conversion, when
the operator= function is commented out
return(0);

}

What does the standard say about this? invoking a constructor when the
object on lvalue is already created...

I think when you comment-out you own definition of operator=, the
default operator= is used. But the default one needs as parameter
const A&, so compiler creates it with constructor A(B&). There is no
other way how to compile it.
 
S

siddhu

Hi Everyone,

I have the following code,

class B
{

};

class A
{
public: A()
{
}
A(B& ref_obj)
{
printf("conversion\n");
}
~A()
{
}
A operator=(const B& ref)
{
printf("operator\n");
return A();
}

};

int main()
{
A obj;
B obj1;
obj = obj1; // invokes the operator=
A obj2 = obj1 // invokes the constructor conversion
obj2 = obj1 // invokes the constructor conversion, when
the operator= function is commented out
obj1 gets converted to a temporary A's object using constructor
conversion, then default assignment operator(provided by the compiler)
is getting called.
 
A

Abhishek Padmanabh

Hi Everyone,

I have the following code,

class B
{

};

class A
{
public: A()
{
}
A(B& ref_obj)
{
printf("conversion\n");
}
~A()
{
}
A operator=(const B& ref)
{
printf("operator\n");
return A();
}

};

int main()
{
A obj;
B obj1;
obj = obj1; // invokes the operator=
A obj2 = obj1 // invokes the constructor conversion
obj2 = obj1 // invokes the constructor conversion, when
the operator= function is commented out
return(0);

}

What does the standard say about this? invoking a constructor when the
object on lvalue is already created...

The conversion constructor is called to create a temporary object of A
to use with the compiler generated assignment operator. Try changing
operator= from this:

A operator=(const B& ref)
{
printf("operator\n");
return A();
}

to this:

A operator=(/* const */ A& ref)
{
printf("operator\n");
return A();
}

and see if it compiles (it shouldn't as temporaries cannot be bound to
reference to non-const). You could easily see all this by writing few
lines of code in place of compiler generated default members with a
bunch of std::cout statements.
 
J

Juha Nieminen

A operator=(const B& ref)
{
printf("operator\n");
return A();
}

operator= should return a reference to "*this", not a new instance.
Else it doesn't make sense to return anything at all.

The semantics of '=' is that it's an expression which value is the
assigned value. If you return a new instance of A you are breaking
this semantic and thus returning anything at all makes no sense.(The
most typical case where this property is used is in expressions like
"a = b = c;" but there are other situations where the property can be
used as well.)

If you don't care about the return value of operator=, then it would
be cleaner to return void.
 
J

James Kanze

I have the following code,
class B
{
};
class A
{
public: A()
{
}
A(B& ref_obj)
{
printf("conversion\n");
}
~A()
{
}
A operator=(const B& ref)
{
printf("operator\n");
return A();
}
};
int main()
{
A obj;
B obj1;
obj = obj1; // invokes the operator=

What else should it do?
A obj2 = obj1 // invokes the constructor conversion

And maybe the copy constructor (which you've not instrumented).
The semantics of this statement are to convert the
initialization expression (here "obj1") to the target type (A),
then initialize the target object using the copy constructor.
The compiler is explicitly allowed to elide the copy, however,
as long as there is an accessible copy constructor. (And since
you don't declare one, the compiler provides one by default.)
obj2 = obj1 // invokes the constructor conversion, when
the operator= function is commented out

If your assignment operator is commented out, the compiler only
has the copy assignment operator that it implicitly generates to
work with. This one takes an A const& as argument, which means
that the compiler must somehow convert obj1 to an A.
return(0);
}
What does the standard say about this? invoking a constructor
when the object on lvalue is already created...

Constructors can be used as conversion operators. If all you
can assign to an A is another A, then the compiler will try to
convert whatever you have to an A. Using a constructor, if it
has to.

After that, the assignment operator is called.

When trying to follow what the compiler is doing in such cases,
I would strongly recommend explicitly defining and instrumenting
the functions that the compiler will otherwise declare and
define implicitly. You might also want to experiment with
declaring some of the non-copy constructors explicit; this is
pretty much standard practice when writing most classes anyway,
since you generally don't want implicit conversions.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,056
Latest member
GlycogenSupporthealth

Latest Threads

Top