Selection of c ++ member functions and non-member functions

Source: Internet
Author: User
Tags types of functions

1. Try to replace the member functions of the class with non-member functions and friend functions.
For example, a class is used to simulate People's Copy codeThe Code is as follows: 1 class People {
2 public:
3...
4 void Getup ();
5 void grouping ing ();
6 void eating ();
7...
8}

In fact, the above three actions are three common actions: "Get up", "Wash", and "eat" in the morning. If a function is used to indicate that the member function isCopy codeThe Code is as follows: 1 class People
2 {
3...
4 void morningAction ()
5 {
6 Getup ();
7 Processing ing ();
8 eating ();
9}
10}

If you write a non-member functionCopy codeThe Code is as follows: 1 void moringAction (People & p)
2 {
3 p. Getup ();
4 p. Grouping ing ();
5 p. eating ();
6}

So do we select a member function of the class or a non-member function of the class?

The object-oriented requirement is to put the functions of operation data together with the data. However, this does not mean selecting a member function. From the perspective of encapsulation, The moringAction encapsulation of member functions is lower than that of non-member functions. If something is encapsulated, it will no longer be visible. The more things are encapsulated, the fewer people can see it. Therefore, classes that use non-member functions are less encapsulated. The less people see it, the more flexible we are to change it, because our changes only directly affect those people who see the changes. Therefore, the more things are encapsulated, the more powerful they are to change.

Consider the data in the object. The less code you can see (access to it), the more data you can encapsulate, and the more we can freely change the object data. Now, if a member function or a non-member function can provide the same function, we select a non-member function.

Before proceeding to the following content, let's talk about the type conversion, display-based conversion, and implicit type conversion in C ++.

2. display type conversion

C ++ has the following display type conversion operators: static_cast, const_cast, dynamic_cast, and reinterpret_cast.

2.1static _ cast
The conversion function has the same meaning as the C style type conversion function. Static_cast can be used to convert non-inherited types. Note 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, however, the non-cosnt type can be converted to the const type. For example:
Char a = 'a ';

Int B = static_cast <int> ();
The conversion between two types is actually implemented by yourself. The conversion principle is similar to that between built-in types.Copy codeThe Code is 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
11 inline int getAge () const
12 {
13 return age;
14}
15
16 inline int getHeight () const
17 {
18 return height;
19}
20
21 People & operator = (const Car & c );
22 private:
23 int age;
24 int height;
25 };
26
27 class Car
28 {
29 public:
30 Car (double c, double w)
31: cost (c), weight (w)
32 {}
33
34 inline double getCost () const
35 {
36 return cost;
37}
38
39 inline double getWeight () const
40 {
41 return weight;
42}
43
44 Car & operator = (const People & c );
45 private:
46 double cost;
47 double weight;
48 };
49
50 People & People: operator = (const Car & c)
51 {
52 age = static_cast <int> (c. getCost ());
53 height = static_cast <int> (c. getWeight ());
54 return * this;
55}
56
57 Car & Car: operator = (const People & c)
58 {
59 cost = static_cast <double> (c. getAge ());
60 weight = static_cast <double> (c. getHeight ());
61 return * this;
62}
63
64 int main (int argc, char * argv [])
65 {
66 Car c (1000.87, 287.65 );
67 People p (20, 66 );
68 People p2 (0, 0 );
69 Car c2 (0.00, 0.00 );
70 p2 = c;
71 c2 = p;
72 std: cout <"car 'info: cost is" <c2.getCost () <". weight is" <c2.getWeight () <std: endl;
73 std: cout <"people 'info: age is" <p2.getAge () <". height is" <p2.getHeight () <std: endl;
74 return 0;
75}

The running result is
Car 'info: cost is 20. weight is 66
People 'info: age is 1000. height is 287

2.2const _ cast
It is mainly used to remove the const and volatileness attributes. In most cases, it is used to remove the const restrictions.

2.3dynamic _ cast
It is used to safely perform type conversion down the inheritance relationship. Dynamic_cast is generally used to convert a pointer or reference to a base class pointer or reference to its derived class, And a null pointer is returned when the conversion fails.

2.4reinterprit _ cast
The most common purpose of this conversion is to convert between function pointer types.Copy codeThe Code is as follows: 1 typedef void (* fun) () // a pointer to a null Function
2 fun funArray [10]; // data containing 10 function pointers.
3 int function (); // a return value is an int type function.
4 funArray [0] = & function () // error! Type Mismatch
5 funArray [0] = reinterpret_cast <fun> (& function); // OK note that the code for converting function pointers cannot be transplanted.

Generally, do not convert the function pointer type.

3. implicit conversion can be performed using non-member functions.
C ++ supports implicit type conversion. For example, implicit type conversion often occurs when an operation is performed or when a parameter is passed to a function.
Suppose you design a class to express rational numbers. In fact, it is a slot to make classes support implicit type conversion. Of course, this is an exception when creating a value type. The following defines a rational number type:Copy codeThe Code is 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 support arithmetic operations, but are not sure whether they are declared as member functions, non-member functions, or friend functions.

First, consider the writing of member functions:Copy codeThe Code is 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 // perform arithmetic operations
10 Rational result = testOne * testTwo;
11 // perform operations with Constants
12 result = testOne * 2; // OK
13 // multiplication satisfies the law of exchange
14 result = 2 * testOne // error !!

So why is the constant incorrect in advance? Here we use another method.Copy codeThe Code is as follows: 1 result = testOne. operator * (2); // OK
2 result = 2. operator * (oneHalf); // error

What happened here? In fact, the so-called implicit type conversion occurs in the first row. Where is implicit type conversion? See the code above. operator * function parameters are of the const Rational type, while 2 is of the cosnt int type ,. The compiler finds that a non-explicit type single parameter class is an int Type constructor and can create a Rational type. So the compiler does that, and implicit type conversion occurs. Therefore, the first statement can run normally, but the second statement does not convert the Rational type to the int type.
It is reasonable to design the normal operation of the above two statements.Copy codeThe Code is 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;
10 result = oneFourth * 2;
11 result = 2 * oneFourth; pass
12}

According to the code above to design a non-member function, implicit type conversion will occur when int type integers are called.
Operaotr * should it be called a friend function of Rational class? This example is completely unnecessary.

If you need to convert the type of all parameters of a function, the function must be a non-member function.

4. Use implicit type conversion with caution
Implicit conversions of some types are powerless because they are the characteristics of the language itself. However, when writing custom classes, we can choose whether to provide functions for the compiler to perform implicit type conversion.
There are two types of functions that allow the compiler to perform implicit type conversion: Single-parameter constructor and implicit type conversion operator.Copy codeThe Code is 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 class
9 public:
10 // convert from int to rational number class
11 Rational (int numerator = 0, int denominatior = 1 );
12...
13}

C ++ supports implicit type conversion. For example, implicit type conversion often occurs when an operation is performed or when a parameter is passed to a function. There are two types of functions that allow the compiler to perform implicit conversion. Single-parameter constructor and implicit type conversion operator.

Some of the conveniences brought about by implicit type conversion may be mentioned earlier. The following describes some troubles.Copy codeThe Code is 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 );
10 Array <int> B (10 );
11...
12 for (int I = 0; I <10; ++ I)
13 if (a = B [I]) {
14 ...}
15 else
16 {
17...
18}

If you accidentally forget to write the subscript of array a, the compiler should report a warning message, but it does not. Because the compiler regards a as an Array <int> type and B as an int, based on the above experience, the compiler sees a non-explicit Single-parameter constructor whose parameter type is int, in addition, operator requires an Array <int> type. Then, the compiler performs implicit type conversion. I believe that this will be very troublesome.
How can we avoid it? Declare the constructor as explicit. Avoid implicit type conversion.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.