构造、析构、赋值运算
Item05:了解C++默默编写并调用了哪些函数。
class Empty
{
public:
Empty() {} //default构造函数
~Empty() {} //default析构函数
Empty(const Empty& rhs) {} //copy构造函数
Empty& operator=(const Empty& rhs) {} //copy复制运算符
};
结论
1.编译器可以暗自为class创建default构造函数、copy构造函数、copy复制运算符、析构函数。
template<class T>
class NameObject
{
public:
NameObject(string& name, const T& value);
private:
string& nameValue;;//reference
const T objectValue; //const
};
//测试程序
int main()
{
string newdog("hugo");
string olddog("piggy");
NameObject<int> p(newdog, 2);
NameObject<int> s(olddog, 5);
p = s;
return 0;
}
2.c++不允许让引用指向不同对象,这时编译器会拒绝进行赋值操作,如果打算在一个含有引用成员的class内支持赋值操作,就必须自定义拷贝赋值运算符。
Item06:若不想使用编译器自动生成的函数,就该明确拒绝
class Unique
{
private:
Unique(const Unique&); //只有声明
Unique& operator=(const Unique&); //不予实现
};
//结论:为了驳回编译器自动提供的功能,可将相应的成员函数声明为private,并且不予实现;
- 结论:为了驳回编译器自动提供的功能,可将相应的成员函数声明为private,并且不予实现;
class Uncopyable
{
protected:
Uncopyable() {}
~Uncopyable() {}
private:
Uncopyable(const Uncopyable&); //只有声明
Uncopyable& operator=(const Uncopyable&); //不予实现
};
class A :private Uncopyable //class不再声明拷贝构造何拷贝赋值运算符
{
//...........
};
//todo page39
Item07:为多态基类声明virtual析构函数
- STL容器禁止派生!!!
Item09:绝不在构造和析构过程中调用virtual函数
class Father
{
public:
Father() { type(); }
virtual ~Father() { cout << "Father dtor!" << endl; }
virtual void type() { cout << typeid(this).name() << endl; } //RTTI
};
class Son : public Father
{
public:
Son() { type(); }
virtual ~Son() { cout << "Son dtor!" << endl; }
virtual void type() { cout << typeid(this).name() << endl; } //RTTI
};
int main()
{
Father* ptr = new Son;
delete ptr;
return 0;
}
- Father class构造的期间virtual函数绝对不会下降到son classes阶层,换言之,在base class构造期间,virtual函数不是virtual函数!
- typeid会告诉我们这点!
- 结论:绝不在构造和析构过程中调用virtual函数!
Item10:令operator= 返回一个 reference to *this
- 为了实现赋值的连锁形式,赋值操作符必须返回一个reference指向操作符左侧的实参;
class Test
{
public:
Test& operator=(const Test& rhs)
{
...
return *this;
}
};