1. Replace the member function of the class with the non-member function of the class and the friend function as far as possible
For example, a class to simulate human people
Copy Code code as follows:
1 class people{
2 Public:
3..
4 void Getup ();
5 void washing ();
6 void eating ();
7..
8}
In fact, the above three actions are morning "get Up", "Wash Celestial", "eat" three common action, if now use a function to represent the use of the member function is
Copy Code code as follows:
1 class people
2 {
3..
4 void Morningaction ()
5 {
6 Getup ();
7 washing ();
8 eating ();
9}
10}
If you write a non-member function that is
Copy Code code as follows:
1 void moringaction (people& p)
2 {
3 P.getup ();
4 p.washing ();
5 p.eating ();
6}
Would you like to select a member function for a class or a non-member function of a class?
Object-oriented requirements are to put the function of manipulating data together with the data. However, this does not mean that you want to select a member function. From the encapsulation point of view, the moringaction encapsulation of the member function is lower than the non member function. If something is encapsulated, it is no longer visible. The more things are encapsulated, the less people can see it. So the class with the non member function is low in encapsulation. And the less people see it, the greater the flexibility we have to change it, because our changes only directly affect the things that see those who change. Therefore, the more things are encapsulated, the greater the ability to change which things.
Consider the data within the object. The less code can see the data (access it), the more data can be encapsulated, and the more we are free to change the object data. Now if a member function, a non member function, can provide the same function, we select the non member function.
Before we say the following, let's talk about type conversions and implicit type conversions in C + +.
2. Display Type conversion
C + + has display type conversion operators are: Static_cast,const_cast,dynamic_cast and reinterpret_cast
2.1static_cast
The conversion function is the same as the C-style type conversion. By using static_cast, you can convert types that do not have an inheritance relationship. However, be aware that you cannot convert a built-in type to a custom type, or convert a custom type to a built-in type, and you cannot remove the cosnt type, but you can convert the NON-COSNT type to a const type. For example:
Char a= ' a ';
int b=static_cast<int> (a);
The conversion between two types, in fact, is also to implement their own support, the principle and the built-in type conversion between the similar.
Copy Code code as follows:
1 #include <iostream>
2 class car;
3
4 class people
5 {
6 Public:
7 people (int a,int h)
8:age (a), height (h)
9 {}
10
One inline int getage () const
12 {
return to age;
14}
15
inline int getheight () const
17 {
return height;
19}
20
People & Operator= (const car& c);
Private:
int age;
int height;
25};
26
Class car
28 {
Public:
Car (double C, double W)
31:cost (c), Weight (W)
32 {}
33
Inline double getcost () const
35 {
;
37}
38
Inline double getweight () const
40 {
Weight return;
42}
43
Car & operator= (const people& c);
Private:
Double cost;
Double weight;
48};
49
People & People::operator= (const car& c)
51 {
Age = Static_cast<int> (C.getcost ());
Height = static_cast<int> (c.getweight ());
The return *this;
55}
56
Car & car::operator= (const people& c)
58 {
Cost = static_cast<double> (C.getage ());
Weight = static_cast<double> (C.getheight ());
return *this;
62}
63
$ int main (int argc,char * argv[])
65 {
Car C (1000.87,287.65);
People P (20,66);
People P2 (0,0);
The car C2 (0.00,0.00);
P2=c;
C2=p;
std::cout<< "Car ' info:cost is" << c2.getcost () <<. Weight is "<< c2.getweight () <<std::endl;
std::cout<< "People ' Info:age is" << p2.getage () <<. The height is << p2.getheight () <<std::endl;
The 0;
75}
Run result is
Car ' Info:cost is 20. Weight is 66
People ' info:age is 1000. The height is 287
2.2const_cast
The main use is to remove the const and Volatileness attributes, most of which are used to remove the const constraint.
2.3dynamic_cast
It is used to safely type conversions down the inheritance relationship. Generally use dynamic_cast to convert pointers or references to base class pointers or references to their derived classes, and return null pointers when the conversion fails.
2.4reinterprit_cast
The most common use of this transformation is to convert between function pointer types.
Copy Code code as follows:
1 typedef void (*FUN)//A pointer to an empty function
2 Fun funarray[10]; Data that contains 10 function pointers.
3 int function (); A return value of type int function
4 Funarray[0] = &function ()//Error! Type mismatch
5 Funarray[0] = reinterpret_cast<fun> (&function); OK note the code that converts the function pointer is not portable.
You should generally avoid converting function pointer types.
3. Implicit conversions can occur with non-member functions
C + + supports implicit type conversions, such as when doing an operation, or when passing arguments to a function, which often occurs implicitly.
Suppose you design a class to represent rational numbers. In fact, making classes support implicit type conversions is a bad decision. Of course, the exception is when creating numeric types. The following defines a rational number type:
Copy Code code as follows:
1 class Rational {
2 Public:
3 Rational (int numerator = 0,int denominator = 1);
4 int numerator () const;
5 int denominator () const;
6 Private:
7..
8}
Rational number types assume support for arithmetic operations, but are not sure whether they are declared as member functions or non member functions or friend functions to implement them.
The first is to consider the member function notation:
Copy Code code as follows:
1 class Rational {
2 Public:
3..
4 Const Rational operator* (const rational& RHS) const;
5..
6}
7 Rational Testone (1,4);
8 Rational Testtwo (1,1);
9//Do arithmetic operations
Rational result = Testone * TESTTWO;
11//and constant operation
result = Testone * 2; Ok
13//multiplication satisfies the law of exchange
result = 2 * Testone//error!!
So why is the constant wrong in advance? Here, let's change the wording.
Copy Code code as follows:
1 result = testone.operator* (2); Ok
2 result =2.operator* (onehalf); Error
What's going on here? In fact, the so-called implicit type conversion occurs in the first line of the equation. Where is an implicit type conversion occurring? Look at the above code operator* function argument is the const rational type, and 2 is a cosnt int type. The compiler found that a single parameter class with a non-explicit type is a constructor of type int, and it can create the rational type. So the compiler did that, and an implicit type conversion occurred. So the first formula works, but the second one does not convert the rational type to an int type.
It is reasonable to design the above two equations to run normally.
Copy Code code as follows:
1 class rational{
2..
3};
4 Const Rational operator* (const rational & LHS, const rational & RHS)
5 {
6 return Rational (Lhs.numerator () * Rhs.numerator (), Lhs.denominator () * Rhs.denominator ());
7}
8 Rational Testone (1, 4);
9 Rational result;
result = Onefourth *2;
One result = 2 * Onefourth; Pass
12}
Designed as a non-member function by the code above, an implicit type conversion occurs when an int type integer is called.
Should operaotr* be called a friend function of rational class? For the purposes of this example, there is absolutely no need.
If you need to type conversions for all parameters of a function, then this function must be a member function.
4. Cautious use of implicit type conversions
There is nothing we can do about implicit conversions of some types, because they are attributes of the language itself. However, when writing a custom class, we can choose whether to provide a function for the compiler to make implicit type conversions.
There are two functions that allow the compiler to perform implicit type conversions: a single parameter constructor and an implicit type conversion operator.
Copy Code code as follows:
1 Public name{
2 Public:
3 Name (const string& s); Convert String to name
4
5..
6};
7
8 class Rational {//Rational number classes
9 Public:
10//conversion from int to rational number class
One Rational (int numerator=0,int denominatior =1);
12..
13}
C + + supports implicit type conversions, such as when doing an operation, or when passing arguments to a function, which often occurs implicitly. There are two types of functions that allow the compiler to make implicit conversions. A single parameter constructor and an implicit type conversion operator.
Perhaps the convenience of some implicit type conversions is mentioned earlier, and here are some of the things that are troubling.
Copy Code code as follows:
1 Template<class t>
2 class array{
3 Array (int lowbound,int highbound);
4 Array (int size);
5 t& operator[] (int index);
6..
7};
8 bool oerpator== (const array<int>& lhs,const array<int>& RHS);
9 array<int> A (10);
Array<int> B (10);
11..
for (int i=0;i < ++i)
if (a = = B[i]) {
14..}
Else
16 {
17..
18}
If the subscript of array A is accidentally forgotten here, the compiler should quote a warning message, but it is not. Because the compiler sees a as the array<int> type, and b is int, according to the experience above, the compiler can see that the parameter type of a non-explicit constructor is int, and operator needs a array<int> type , the compiler does this, and an implicit type conversion occurs. I believe that if this happens, it will be troublesome.
How to avoid it? Declare the constructor as explicit. Avoidance of implicit type conversions.