芝士wa
2024.4.2
Item20链接
“缺省情况下,C++以传值的方式将对象传入或传出函数,这种传递方式会带来昂贵的代价。”
举例分析:
class Person {
public:
Person(); // parameters omitted for simplicity
virtual ~Person(); // see Item 7 for why this is virtual
...
private:
std::string name;
std::string address;
};
class Student: public Person {
public:
Student(); // parameters again omitted
virtual ~Student();
...
private:
std::string schoolName;
std::string schoolAddress;
};
考虑以下代码,
bool validateStudent(Student s); // function taking a Student
// by value
Student plato; // Plato studied under Socrates
bool platoIsOK = validateStudent(plato); // call the function
首先创建了一个学生对象,然后通过传值的方式调用函数,在这次函数调用时,发生了什么呢?形参的拷贝!
一个Student对象内部包含了两个string,当我们创建student的时候,也构造了两个string,同时,因为student继承了Person,一个person对象也被构造出来,而Person内部又包含另外两个string对象。
最终,以传值方式传递一个Student对象的后果就是导致:
- 一次Student拷贝构造函数的调用
- 一次Person拷贝构造函数调用
- 四次string拷贝构造函数调用
- 六次析构函数调用
采用传引用的方式可以避免这些拷贝,
bool validateStudent(const Student&s);
"以传引用方式传递形参还可以避免slicing problem(切断问题)。"
考虑下面的代码:
class Window {
public:
...
std::string name() const; // return name of window
virtual void display() const; // draw window and contents
};
class WindowWithScrollBars: public Window {
public:
...
virtual void display() const;
};
下面的函数原意是实现打印并显示的功能,
void printNameAndDisplay(Window w)
{
std::cout<<ww.name();
w.display();
}
//调用
WindowWithScrollBars wwsb;
printNameAndDisplay(wwsb);
形参wwsb通过值传递给函数,实际上这里的wwsb会被当成window类的对象,display调用总是调用Window::display,而不是WindowWithScrollBars::display,多态无法实现。
绕过slicing problem(切断问题)的方法就是以传const引用方式传递wwsb。
void printNameAndDisplay(const Window& w);
现在w将表现出WindowWithScrollBars的特性。
“如果你有一个内建类型的对象,例如int,以传值方式传递它常常比传引用的方式更高效”
通常情况下,对于内建类型,STL iterator(STL迭代器)和函数对象类型,采用值传递的方式会更高效,对于其他类型,用传const引用代替传值。
标签:std,const,string,Person,Item20,Student,用传,public From: https://www.cnblogs.com/cheese-wa/p/18110186