C++ 技术中心

   :: 首页 :: 联系 ::  :: 管理
  154 Posts :: 0 Stories :: 84 Comments :: 0 Trackbacks

公告

郑重声明:本BLOG所发表的原创文章,作者保留一切权利。必须经过作者本人同意后方可转载,并注名作者(天空)和出处(CppBlog.com)。作者Email:6549168@qq.com

留言簿(6)

搜索

  •  

最新随笔

最新评论

评论排行榜

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=中处理“自我赋值”
   
posted on 2014-11-14 14:00 C++技术中心 阅读(1446) 评论(0)  编辑 收藏 引用 所属分类: C++ 基础

只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理