Reputation: 123
I am sorry if it is duplicated question, but i didn't find a discussion of exactly this question. So, i am learning C++ and i don't understand the following issue with the assignment of values to class objects. I have this implementation of the class T:
class T
{
int aInt;
double aDouble;
public:
T():aInt(0),aDouble(0.){}
T(int my_aInt, double my_aDouble):aInt(my_aInt), aDouble(my_aDouble){}
T(int my_aInt):aInt(my_aInt), aDouble(0.){}
T(double my_aDouble):aInt(0), aDouble(my_aDouble){}
void set_aInt(int my_aInt){
aInt = my_aInt;
}
void set_aDouble(double my_aDouble){
aDouble = my_aDouble;
}
int get_aInt(){
return aInt;
}
double get_aDouble(){
return aDouble;
}
};
I want to create the objects of this class and assign some values to them. I can do it in this way:
T tt1(-1, 5.), tt2(-1), tt3(5.);
and it works fine. Now i want to change the values assign to object tt1. I know that i can do it like this:
tt1.set_aInt(-3); // gives aInt = -3, aDouble = 0
tt1.set_aDouble(6.); // gives aInt = 0, aDouble = 6.
and it also works fine. But it seems there is another way to do it:
tt1 = -3; // gives aInt = -3, aDouble = 0
tt1 = 6.; // gives aInt = 0, aDouble = 6.
tt1 = (-3, 6.); // gives aInt = 0, aDouble = 6. - Why?
My first question is: Is tt1 = -3;
equivalent to tt1.set_aInt(-3);
and is it a good practice? The second question is what is wrong with tt1 = (-3, 6.);
and why it sets value of aInt equals to 0 instead of -3?
Upvotes: 5
Views: 153
Reputation: 1618
When you write tt1 = -3
this is equivalent to
T temp(-3);
tt1 = temp;
In C++, a constructor that takes a single argument acts as an implicit conversion operator. So the compiler looks at tt1 = -3
and sees that it can convert -3 to a T
type using your constructor in a temporary variable and then use the default =
operator to assign the value to tt1
. The assignment to 6.
works similarly except that the constructor that takes a single double is used. If you prepend the constructor with explicit
it will not be used for conversions like this.
When you type tt1 = (-3, 6.)
you are invoking the comma operator. In C/C++, (x,y)
evaluates to y
, so this is really equivalent to tt1 = 6.
Upvotes: 2
Reputation: 21
it is good to provide set_aInt so that you can track where the value passes on to in class where as it is equal as to pass tt1 = -3; while (-3,6) is passed to class T Probably the override as accepted the integer value but it erased it and passed the double value 6. due to which you faced a problem. While you initialize separately two instances of allocation take place and allocate value, But in single initialization the updated value which overrides previous value goes into the class
Upvotes: -4
Reputation: 5557
You should mark the single argument constructors explicit
, because defining a single argument constructor also creates an implicit conversion from the argument type to the constructed type in C++, which is typically not desired.
tt1 = -3;
is thus equal to:
tt1 = T(-3);
i.e. it uses copy/move assignment. In the second case, the (-3, 6.)
is just parenthesis around the statement -3, 6.
, where ,
is the sequence operator. The statement thus evaluates to 6.
, and the implicit conversions using the double
constructor is chosen.
Upvotes: 7