编译器默认为类生成:构造、析构(非虚)、拷贝构造(浅)、拷贝赋值(浅)
1:
构造函数。
成员初始化列表
初始化列表带上基类,传递参数,不然会用默认的构造函数构造基类。
2:
析构函数
1)pure需要定义,因为会被调用,(建议不pure)
2)别让异常逃离。
3) 一般来说,带有虚函数的类,都需要虚析构函数(如果明确不是做基类,那就没必要虚析构函数)
带虚函数,类大小会大一个指针大小。
【1/2 注意】
别在构造、析构中调用虚函数(如:派生类构造时,基类调用虚函数,按理和实际不现实)
base构造期间,虚函数不是虚函数。(派生类的函数还没放到虚函数表中。况且,逻辑上也不能访问未构造的成员)
3:
拷贝构造函数
Base(const Base &obj);
4:
拷贝赋值运算符
1)返回 reference to *this 应对 连续赋值
2)析构与构造的结合体。
3)处理自我赋值
如:
class Widget
{
...
private:
Bitmap *m_pb;
}
(1)
Widget &Widget::operator=(const Widget &rhs)
{
if (this == &rhs) return *this;
delete m_pb;
m_pb = new Bitmap(*rhs.m_pb);
return *this;
}
(2)如果new 有异常,那么m_pb就指向了被删除的内存。
Widget &Widget::operator=(const Widget &rhs)
{
// 可以没有证同测试,自己估计“自我赋值发生的概率”,可以加上
Bitmap *pOld = m_pb;
m_pb = new Bitmap(*rhs.m_pb);
delete pOld;
return *this;
}
(3)保证异常安全且自我赋值安全
Widget &Widget::operator=(const Widget &rhs)
{
Widget oTmp(rhs);
swap(oTmp);
return *this;
}
注:操作一个以上对象:自我赋值的考虑
【3/4 注意】
1)拷贝构造与赋值运算符不能互调。
拷贝构造
{
赋值(赋值只作用于已初始化的对象)
}
赋值
{
拷贝(构造一个已存在的对象,没有语法支持)
}
2)抑制拷贝方法:1.定义自己的 2.基类私有且不实现(如Uncopyable)
3)赋值对象时勿忘每一个成分(包括派生类要 手动赋值基类的部分Base::operator=(rhs))
备用:
5:虚:重载、覆盖、隐藏
virtual/ 同参
转载请注明原文地址: https://ju.6miu.com/read-676809.html