Recently, I read Thinking in C++;
In chapter 12 about operator overloading, I was confused about why the constant can directly be brought to a object (eg: b1 = 9; b2 = 47;)
please tell me
In below is a whole codes.
Recently, I read Thinking in C++;
In chapter 12 about operator overloading, I was confused about why the constant can directly be brought to a object (eg: b1 = 9; b2 = 47;)
please tell me
In below is a whole codes.
Others that know the internals of C++ better than me are welcome to answer.
I do not think that a constant is being assigned directly to the lvalue type Byte. Rather, I think the compiler converts the constant “9” to rvalue type Byte first, and then assigns that Byte object to lvalue b1.
@Pharap ?
Indeed, there is an implicit constructor for Byte
that takes as a single parameter an unsigned char
:
public:
Byte(unsigned char bb = 0) : b(bb) {}
Unless you declare such a constructor with explicit
, it’ll be called directly when needing a Byte
while using an integer literal.
Adding explicit
would require you to do b1 = Byte(*);
instead.
Thanks everyone !!!
According to your explanation, I supposed the complier do something below about " b1 = 9 ":
1、look for “=” operator overloading, and find “Byte object = Byte object”
2、find rvalue is a constant, and try to look for how to convert to a Byte object in Byte class constructors
3、find a constructor using only argument of int, and try to Byte(9) to build a Byte object.
4、finially, using “=” operator overloading
BUT!!! This is only a supposition!!!
@carbonacat’s answer is correct about why it’s possible.
If there’s a (non-explicit
) constructor for a type T
that accepts a single parameter of type U
(or const U &
) then using an assignment operator t = u;
(where t
is an object of type T
and u
is an expression of type U
) will match that constructor.
However, it behaves slightly differently depending on the context…
For T t = u;
, the code is translated to T t(u)
, i.e. the constructor is called directly.
For t = u;
(where t
has already been declared), the code is translated to t = T(u)
,
i.e. a temporary object of type T
is created from u
and then assigned to t
.
Technicallly it would find:
Byte & Byte::operator=(const Byte &)
- the ‘copy assignment operator’Byte & Byte::operator(Byte &&)
- the ‘move assignment operator’Both of which are implicitly declared by the compiler and would be functionally equivalent.
Actually it would find:
Byte::Byte(unsigned char bb = 0)
- a single parameter constructor (with a default argument)It would then attempt to implicitly convert the integer literal (of type int
) to an unsigned char
,
which it can do because there’s an implicit conversion between the two.
So actually there’s two implicit conversions happening:
int
-> unsigned char
unsignec char
-> Byte
Usually the term ‘operator overloading’ is only applied if there are user-defined operator overloads.
In this case operator=
only has implicitly-defined overloads,
so most people wouldn’t refer to it as ‘operator overloading’.
Lastly I’d like to say that the code in “Thinking in C++” does a few things I’m not happy about.
using namespace std;
is bad practiceoperator&&
and operator||
is bad practiceint
from an overloaded comparison operator (operator<
, operator>
, operator<=
, operator>=
, operator==
, operator!=
) is bad practice - they should return bool
.
const Byte
instead of just Byte
, which is redundant and compilers will complain about this (i.e. they will provide a warning)
(Byte(5) + Byte(6)) = Byte(7);
fail to compile, but these days it’s considered bad practiceconst T
, returning const T &
is something entirely differentByte()
initialises the internal value to 0
can negatively affect performance, instead there should be two constructors:
Byte() = default;
Byte(unsigned char b) : b(b) {}
b
, b1
, b2
, k
) is generally a bad idea. Good code should have meaningful variable namesb1 = b2 = b3;
makes me frown. One assignment per statement please.TRY2
is generally bad, don’t do it in any serious code if you can avoid it.Thanks Pharap!!!
I’m agree with you about that code has a few issue.
but I think <Thinking in C++> better than other books in respect about how to understand easily in C++.