在编写函数的返回值和形参的时候,能 传引用(pass by reference) 就不要 传值 (pass by value).
这样是为了少调用 copy constructor ,可以提高效率。
另外 传递& 引用,可以像用指针一样,能实现 “父类指针指向子类实例”的多态效果,传值没有多态的效果。
比如有类
class Person
{
private:
string name,address;
public:
Person()
{
cout << "Person constructor."<<endl;
}
Person(const Person& p)
{
/*name = p.name;
address = p.address;*/
cout << "Person copy constructor" << endl;
}
~Person()
{
cout << "Person destructor."<<endl;
}
};
class Student:public Person
{
private:
string schoolName,schoolAddress;
public:
Student()
{
cout << "Student constructor."<<endl;
}
Student(const Student& s)
{
cout << "Student copy constructor"<<endl;
}
~Student()
{
cout << "Student destructor."<<endl;
}
};
函数 returnStudentTwo() 比 returnStudentOne() 效率高, 因为引用形参 &s 不必再调用拷贝构造函数来构造新的对象,只是另1个对象的别名。
Student returnStudentOne(Student s)
{
return s;
}
Student returnStudentTwo(const Student& s)
{
return s;
}
const Student& returnStudentThree(const Student& s)
{
return s;
}
返回值也同理, returnStudentThree() 比 returnStudentTwo() 效率更高,因为引用形式的返回值也不需要调用拷贝构造函数。
但是引用作为返回值的时候需要注意,
绝不能返回 local 对象的reference ,这时必须要以传值的形式作为返回值。
比如函数 returnTestOne().在其他函数调用它的时候, 会产生不可预知的错误! 因为 s 在stack 内存, 函数结束时已回收, 而调用此函数的返回值,用的还是 s 这块内存,会非常危险。
returnTestTwo() 虽然用指针解决了这个问题,但是在函数中开辟的Heap内存,在外界非常容易忘记delete, 所以这样的写法会非常容易造成 memory leak .
所以,在需要值传递( pass by value )的时候 ,就老老实实写成 returnTestThree() 这种函数.
const Student& returnTestOne()
{
Student s;
return s;
}
const Student& returnTestTwo()
{
Student *s = new Student();
return *s;
}
const Student returnTestThree()
{
Student s;
return s;
}
以上这些内容就是复述一遍 effective c++ 里面的一些知识点,
道理虽然不难,但是还是自己上机写个 console 程序看看 log 印象更深刻一些。
并且平时也应该注意和运用书上所说的知识点才行。