【Effective C++ Sumary】实现

本文探讨了C++编程中的若干最佳实践,包括延迟变量定义、减少转型操作、使用新式转型、避免返回对象内部成分的引用、确保异常安全性、合理使用inline函数、降低文件编译依赖等,旨在提高代码质量和效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

26.尽量延后变量定义的出现时间,可以增加程序的清晰度并改善程序效率,因为有的变量定义太靠前了,可能后面用不到

27.尽量少做转型操作

C++有四个新式转型

const_cast<T>   将对象的常良性移除(唯一有此能力的转型符)

dynamic_cast<T>  安全向下转型(继承体系中)  唯一无法用旧式语法执行的

reinterpret_cast<T> 执行低级转型

new_type必须是一个指针、引用、算术类型、函数指针或者成员指针。它可以把一个指针转换成一个整数,也可以把一个整数转换成一个指针(先把一个指针转换成一个整数,再把该整数转换成原类型的指针,还可以得到原先的指针值)。

static_cast<T> 相当于强制转换

尽量用新转型,比较容易识别

28.避免返回handles指向对象内部成分

成员变量的封装性最多只等于“返回其reference”的函数的级别

如果一个const成员函数传出一个reference 后者所指数据与对象自身有关联,那么外部就可以修改这个内部数据,const 成员函数绝对不能返回指针或者引用

29.异常安全函数 即使发生异常,也不会泄露资源或者允许任何数据结构被破坏 这样函数有三种:

基本型:如果异常被抛出,程序内的任何事物仍然保持在有效状态

强烈型:异常被抛出 ,程序状态不改变。如果成功,那么没问题,如果失败,程序会回复到“调用函数之前的状态”

不抛掷: 函数后面加throw()  ,并不是说绝不会抛出异常,由函数实现决定。

 

30.inline函数可能导致Obj code变大,inline只是一个建议,具体还是看编译器和代码实现。

比如构造,析构,虚函数一般不会inline  不然如果构造发生变化,所有用到的地方都需要重新编译

如果是non inline只需要重新链接

31.

将文件编译依存性降到最低

原文:https://blog.youkuaiyun.com/HLW0522/article/details/82961031

考虑以下代码

class A
{
public:
    A() { cout << "A" << endl; }
    ~A() { cout << "des A" << endl; }
    void output() { cout << "A" << endl; }
};
class B
{
public:
    B() {}
    void output() { cout << "B" << endl; }
};
 
class C
{
public:
    C(const A & _a, const B &_b) {
        a = _a;
        b = _b;
    }
    void output() {
        a.output();
        b.output();
    }
private:
    A a;
    B b;
};
由于类C中有A,B的成员对象,所以当a,b有一点改变,C类就需要重新编译,需要重新编译的原因如下。假设在main函数中

void main()
{
    int x;
    C c;
}
对于x编译器可以明确的知道需要分配Int大小的内存,而对于对象c也需要知道需要分配多少空间来存放,所以它就需要询问c的定义。而C中有A的对象,A被改变了,需要重新编译,那此时C就需要重新编译了。

此问题可以通过一个名为 pointer to implementation的方法来改变,即将a,b的操作否放在实现类CImpl中,而C类中存放方一个指向实现物的指针。代码如下

class CImpl
{
public:
    //CImpl() {}
    CImpl(const A & _a, const B &_b) {
        a = _a;
        b = _b;
    }
    void output() {
        a.output();
        b.output();
    }
private:
    A a;
    B b;
};
 
class C
{
public:
    C(const A & a, const B &b) :pImpl(new CImpl(a, b)) {}
    void Output() 
    {
        pImpl.get()->output();
    }
private:
    shared_ptr<CImpl> pImpl;
 
};
此时C中只存放了一个指针的大小,不管A,B如何改变都不影响C了

还有一种方法可将接口与实现分离,代码如下

class C
{
public:
    C() {}
    virtual ~C() {}
    virtual void output() = 0;
    static shared_ptr<C> create(const A&, const B&);
};
 
class RealC:public C
{
public:
    RealC() {}
    RealC(const A & _a, const B &_b):a(_a),b(_b)
    {
    }
    
    ~RealC() {}
    void output() 
    {
        a.output();
        b.output();
    }
private:
    A a;
    B b;
};
shared_ptr<C> C::create(const A&a, const B&b)
{
    return shared_ptr<C>(new RealC(a, b));
}
调用时只需要C::create()->output();即可
条款31
 
 
 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值