实现、继承与面向对象设计

2018-03-23  本文已影响0人  szn好色仙人
条款26 尽量延后变量的定义式出现的时间
条款27 尽量少做转型动作
条款28 避免返回一个handles指向对象的内部成分
class CTest
{
public:
    CTest()
    {
        pValue = new int(0);
        printf("new:0x%08x\n", pValue);
    }
    ~CTest()
    {
        printf("delete:0x%08x\n", pValue);
        delete pValue;
    }
    const int* GetValue() const {return pValue;}

private:
    int *pValue;
};

CTest Fun()
{
    return CTest();
}

int main()
{
    int* pTem = const_cast<int*>(Fun().GetValue());
    printf("main:0x%08x\n", pTem);
    *pTem = 100;//其实这里访问的内存是未分配的,vs2010下却不会崩溃
    return 0;
}

/*
输出:
new:0x00033690
delete:0x00033690
main:0x00033690
*/

const int* GetValue() const {return pValue;}虽然用const来保证返回的指针是可读的,但是无法保证用户会对这个指针干出什么事情,更大的问题是比如上述的Fun函数,会导致pTem变为空悬指针而导致访问异常

条款29 为异常安全而努力是值得的
条款30 透彻了解inline的里里外外
条款31 将文件间的编译依存关系降至最低
条款32 确定你的public继承塑模出is-a关系
条款33 避免遮掩继承而来的名称
条款34 区分接口继承和实现继承
条款35 考虑virtual函数以外的其他选择
条款36 绝不重新定义继承而来的非虚函数
条款37 绝不重新定义继承而来的缺省参数值
class CFather
{
public:
    virtual void FunTest(int nValue = 4096)
    {
        printf("Fahter:%d\n", nValue);
    }
};

class CChild : public CFather
{
public:
    CChild(){}

public:
    void FunTest1(int nValue = 0)
    {
        FunTest(nValue);
    }

private:
    virtual void FunTest(int nValue)//不提供默认参数
    {
        printf("Child:%d\n", nValue);
    }
};

int main()
{
    CChild Child;   
    Child.FunTest1();   //Child:0
    return 0;
}
条款38 通过复合塑模出"has-a"或"根据某物实现出"
class CTest0
{
};

class CTest1
{
private:
    CTest0 Test0;  //这就是复合
};
条款39 明确而谨慎的使用private继承
条款40 明智而谨慎的使用多重继承
上一篇 下一篇

猜你喜欢

热点阅读