This article focuses on two issues:
(1) why sometimes forced conversion succeeds while writing code, but some types cannot? Is this a C ++ kernel rule or a custom rule?
(2) How can I use an integer or string value controlled by the kernel to initialize a custom class object? For example, self_defined_class a = 100; self_defined_class a = "123"; instead of self_defined_class a (123) or self_defined_class a ("123 ");
The answer to the first question is: the rule for force type conversion is kernel-defined + User-defined, that is, some rules are kernel-defined, and some support extensions, rather than kernel-limited rules.
Whether the two types of objects can be forcibly converted has no absolute relationship with the object size.
[Rule 1] In the default rule, only large objects can be converted to small objects, just as subclass objects can be assigned to parent objects, but parent objects cannot be assigned to subclass objects. For example:
class A{public:int a;} ;class B:public A{ public: int b;} ;
For such a class, the following statements are correct:
A aa; B bb; aa=bb;
However, if the value is assigned in turn, the following statements are incorrect:
A aa; B bb; bb=aa;
What if we must use the parent class to initialize the subclass object ?? In fact, it can also be very simple. You only need to add constructor B as follows:
class A{public:int a;} ;class B:public A{ public: int b; B(){b=0;} B(A aa){b=aa.a;a=aa.a;}} ;
After this definition, the above two write methods are correct.
We can understand as follows: why does the C ++ kernel rule only assign values to the parent class object to the subclass object, but not to the parent class object to the subclass object ?? The answer is: we can understand that C ++ does not allow users to do anything in kernel rules in another way. As we can imagine, if the C ++ kernel does not implement the assignment of a subclass object to the parent class object, then the awesome programmer will not be able to implement it using C ++. We can see that if C ++ is not implemented, we should use the following code:
class A{public:
A(B b){a=b.a;}int a;} ;class B:public A{ public: int b; B(){b=0;} B(A aa){b=aa.a;a=aa.a;}} ;
However, it is obvious that this code is impossible, because B is A derived class of A and must be defined after A, but no B is defined when A is defined, what about A (B B) {a = B. a?
From this we can see that the refining of C ++ kernel rules gives programmers the greatest freedom. Rules are used to resolve conflicts without limiting others.
Here we will discuss another point, that is: why do we need to copy constructors?
In the early stage, the C ++ designers must assign values to each other between similar objects. Based on the above analysis, if you use a common constructor such
B (B B ){...}
Because B is also a Class B instance, temporary variables are used to accept input parameters and will be generated at the same time when the instance is declared. This result leads to an infinite loop. So smart designers invented Copy Constructor.
B (B & B ){....}
In this way, the method of transferring values is changed to pass names, and the essence of object B is changed to B rather than B, so that no temporary object variable is generated. It will not trigger new constructor.
Default:
[Rule 2] C ++ adds a copy constructor to each custom class by default to support mutual conversion between objects of the same type.
(2) after learning the above knowledge, I believe that question 2 is very simple. You only need to add a constructor for your class, you can put the C ++ kernel variables int, float, string and so on are directly assigned with equal sign =. This is a cool thing.
So why can the constructor be triggered with the = sign? After all, I didn't declare a New Type object ??
The answer is another rule of the C ++ kernel:
Rule 3: C ++ adds an equal sign = overload function for each custom class by default, which is used to assign values to equals signs between objects of the same type.
= The parameter of the number overload function is the right value, which should be a const B & or B Variable. Before the value assignment operation, a forced conversion is executed first. If the conversion is successful, the value is assigned, if not defined, the compilation fails.
Through today's discussion, we know that the core part of C ++ kernel rules is very simple, that is, basic grammar + basic type. Other rules are used to patch the language system to solve various contradictions (or problems). I call them "support rules ". Therefore, if you have a C ++ book, you should not start with the tedious "supporting rules", but from the simplest statements to explain why this rule should exist one by one. I believe that C ++ will become less mysterious.