Effective C ++ Item 20: Design and declaration (rather to pass-by-reference-to-const replace pass-by-value)

First, call-by-result in low efficiency of code execution

  • Why call by value will result in low efficiency of code execution? Because when the call-by, and is a copy of the transfer object, so the object is to call the copy constructor will copy the object, and then passed to the function. Efficiency is relatively low

  • Let's look at an example: There is a base class (the Person) with a derived class (Student), and the definition of a function (validateStudent), accepts a Student object parameters (call-by)
class Person
{
public:
    Person();
	virtual ~Person();
private:
    std::string name;
    std::string address;
};

class Student :public Person
{
public:
    Student();
    ~Student();
private:
    std::string schoolName;
    std::string schoolAddress;
};

bool validateStudent(Student s);
  • Now we have the following code:
int main()
{
    Student plato;          //定义Student对象
    validateStudent(plato); //传值调用
    return 0;
}
  • Now let's think about this for a call-in process altogether what's happening:
    • ① executed six constructors: plato passed into the function when you need to call the constructor 1 Student, we need to construct Person former Student constructor executes, and therefore will call the constructor 1st Person class. Person and Student classes in a total of four two string member variables, it is also necessary to call the constructor string 4 times
    • ② performed destructor 6: When the function is executed, a copy of the incoming plato validateStudent functions need to be performed in a destructor, then the time to execute the destructor correspond respectively to perform six destructor (Student + Person + 4 string member variables)

Alternative: transfer calls to const reference

  • An alternative call-by-object is passed to the function as const reference:
    • const: If you do not want to object is modified in the function, then to modify const
    • References: a reference in the form of a pointer to the bottom of the compiler. Thus the use of the reference object to the transfer function, the object is directly passed to a function, rather than to pass the copy of the object function (to avoid the call and call the destructor constructor)
  • Now we modify the above validateStudent function:
bool validateStudent(const Student& s);

int main()
{
    Student plato;          //定义Student对象
    validateStudent(plato); //const引用调用
    return 0;
}

Second, the call-by will cause the object cutting / truncation problem

  • Object cut / cut: if an object to be called directly by value, will result in cutting the object / truncation problem. This phenomenon generally occurs in the base class as function parameters, but to shift the transfer function derived object
  • About truncated example of an object can also see this article in the title seven: h6ttps: //blog.csdn.net/qq_41453285/article/details/10310043
  • Let's look at an example: There is a base class (Window) with a derived class (WindowWithScrollBars), and the definition of a function (printNameAndDisplay), accepts a Window object parameters (call-by)
class Window
{
public:
    std::string name()const;
    virtual void display()const;
};

class WindowsWithScrollBars :public Window
{
public:
    virtual void display()const;
};

void printNameAndDisplay(Window w)
{
    std::cout << w.name();
    w.display();
}
  • Now we have the following code:
int main()
{
    WindowsWithScrollBars wwsb;
    printNameAndDisplay(wwsb);  //WindowsWithScrollBars对象会被截断
    return 0;
}
  • Now let's think about this for a call-in process altogether what's happening:
    • Since the parameters for the function printNameAndDisplay Window type, even if we pass WindowsWithScrollBars type object, then the object will be cut off, only the contents belonging to the base class taken (Window) WindowsWithScrollBars the object, and then passed to the function
    • So after being cut off, regardless of the call, printNameAndDisplay function call display function is always the Window display virtual function, the display will not be WindowsWithScrollBars virtual function. Because only occurs polymorphism in a case where a base pointer / reference to point to a derived class, where there is no pointer / reference

Alternative: transfer calls to const reference

  • If we changed the parameter of the function const reference, then passed into the function of the object will be associated with the incoming object type
  • Now we modify the above validateStudent function:
void printNameAndDisplay(const Window& w)
{
	std::cout << w.name();
	w.display();
}

int main()
{
    WindowsWithScrollBars wwsb;
    printNameAndDisplay(wwsb);  //传入的就是WindowsWithScrollBars类型的对象
    return 0;
}

Third, the built-in type recommended call-by

  • C ++ compiler bottom, the reference is implemented in the form of a pointer, and therefore reference is passed pointer is passed
  • If you use an object belonging to the built-in types (such as int), built-in types are quite small, call-by often more efficient than those passed by reference
  • This rule in iterators and function objects in the STL have been widely cited in

IV Summary

  • Try to replace pass-by-value to pass-by-reference-to-const. The former is usually more efficient, and to avoid cutting issues
  • The above rule does not apply to the built-in type, and STL iterator and function objects. For them, traditional values ​​are often more appropriate to call
Released 1463 original articles · won praise 996 · Views 350,000 +

Guess you like

Origin blog.csdn.net/qq_41453285/article/details/104251160