条款05:了解c++默默编写并调用哪些函数
编译器会为类声明构造函数、拷贝构造函数、拷贝运算符和析构函数。
class Empty {
};
等价于:
class Empty {
public:
Empty() { } //构造函数
Empty(const Empty &rhs) { } //拷贝构造函数
~Empty() { } //析构函数
Empty &operator = (const Empty &rhs) { } //拷贝运算符
};
- 这些函数被调用时,才会被编译器创建出来。
- 如果类中含有引用成员、const成员,则必须自己定义拷贝操作符。
- 编译器为类产生的析构函数是非虚函数,除非这个类的基类声明有虚析构函数。
- 编译器产生的拷贝构造函数和拷贝运算符,仅将对象的non-static成员变量拷贝到目标对象。
#include <iostream>
#include <string>
using namespace std;
template<typename T>
class student{
public:
student(const string &name, const T& age);
private:
string m_name;
T m_age;
};
template<typename T>
student<T>::student(const string &name, const T& age):m_name(name),m_age(age)
{
}
int main(){
student<int> stu("Jenny", 3);
student<int> stu2(stu); //编译器自动创建拷贝构造函数
system("pause");
return 0;
}
上例类中含有构造函数,编译器不再为类创建默认构造函数。
student中没有声明拷贝构造函数和拷贝操作符,在需要调用时,编译器会自动创建。
上例中当m_name是引用,m_age是const T时:
#include <iostream>
#include <string>
using namespace std;
template<typename T>
class student{
public:
student(string &name, const T& age); //string不能是const,因为m_name是引用non const string
private:
string& m_name;
const T m_age;
};
template<typename T>
student<T>::student(string &name, const T& age):m_name(name),m_age(age)
{
}
int main(){
string str1("Jenny");
student<int> s1(str1, 3);
string str2("Dave");
student<int> s2(str2, 3);
s1 = s2; //编译会出错,因为operator = 此时不可用
system("pause");
return 0;
}
总结
编译器会为类声明构造函数、拷贝构造函数、拷贝运算符和析构函数。