c++基础要点(9-15点)

c++基础要点(9-15点)
9. 若不想使用编译器自动生成的函数,就该明确的拒绝

#include "stdafx.h"
#include < string>

using  namespace  std;

class UnCopyAble
{
protected:
    UnCopyAble(){}
    ~UnCopyAble(){}

private:
     // 放入private,则不允许使用拷贝构造和对象间赋值
    
// 即使不慎在 membre或friend中使用,则链接通不过。
    
// 原因是只有声明
    UnCopyAble( const UnCopyAble&);
    UnCopyAble&  operator=( const UnCopyAble &);
};

class HomeForSale :  private UnCopyAble  // class 不再声明copy构造函数和赋值重载
{
public:

};

int _tmain( int argc, _TCHAR* argv[])
{
    HomeForSale sale1;
    
    
     // 以下将不允许
    HomeForSale sale2(sale1);

     // 以下将不允许
    HomeForSale sale3;
    sale3 = sale1;
     return 0;
}
10.为多态基类声明virtual析构函数
   
   总结:带有多态性质的基类应该声明一个virtual析构函数。如果class带有任何virutal,它也应该拥有一个virtual析构函数。
class设计目的不是作为基类来使用的,或不是为了具备多态性,就不应该声明virutal析构函数(一个类如果加入了virutal函数,则类大小
会发生变化。因为有包含virutal table pointer)。

11. 别让异常逃离析构函数
 
 析构函数绝对不要吐出异常,这样会带来“过早结束程序”或“发生不明确行为”。如果一个析构函数可能要抛出异常,析构函数应该捕捉任何异常,然后吞下
它,或者结束程序。如果要在某个函数运行时抛出的异常做出反应,那么class应该提供一个普通函数执行这个操作。例如下:
class DBConn
{
public:

     // 供客户使用的函数
     void Close()
    {
        db.close();
        closed =  true;
    }

    ~DBConn()
    {
         if(!closed)
        {
             try
            {
                db.close();  // 关闭连接,如果客户不调用Close的话
            }
             catch ( )
            {
                 // 写入日志,记下close调用失败
            }
        }
    }

private:
    DBConnection db;
     bool closed;
12. 绝不在构造和析构过程中调用virtual函数
//  testss.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include < string>
#include <list>

using  namespace  std;


class Transaction
{
public:
    Transaction();
     void init();
     virtual  void logTranscation() = 0;

};

Transaction::Transaction()
{
    init();
}

void Transaction::init()
{
    logTranscation();
}

class BuyTransaction :  public Transaction
{
public:
     void logTranscation()
    {
        printf("BuyTransaction log \n");
    }
};


int _tmain( int argc, _TCHAR* argv[])
{
    BuyTransaction b;
     return 0;
}
以上代码,会有一个BuyTransaction构造函数被调用,但首先是Transaction更早被调用。在derived class对象的base class构造期间,对象的类型是base class.若使用运行期类型信息,也会把对象视为base class类型。本例,构造函数中调用init,而init中调用Transaction::logTransaction。而logTransaction又是抽象方法,导致程序异常中止。当然如果非抽象方法,则会调用Transaction中的logTransaction。

    同样,析构函数,一旦derived class析构函数先开始执行。对象内的derived class成员变量便呈现现未定义值。所以c++视它们不存在。进入base class析构函数后对象就成为一个base class对象。

13. 令operator=返回一个reference to *this
14. 在operator=中处理“自我赋值”
   

你可能感兴趣的:(c++基础要点(9-15点))