effective C++ 阅读笔记 3

条款41 了解隐式接口和编译期多态

//显式接口:函数的签名式(函数名称、参数类型、返回类型)构成
class Widget{
public:
    Widget();
    virtual ~Widget();
    virtual std::size_t size() const;
    virtual void normalize();
    void swap(Widget& other);
};


//隐式接口 由表达式组成
template<typename T>
void do(T & t)
{
    if(w.size() > 10 && w != some)
    {
    ...
//它必须提供一个名为size的成员函数,该函数返回一个整数值
//它必须支持一个operator!= 函数,用于比较两个T对象

编译期多态是因为template通过具现化和函数重载解析发生在编译期。

 

条款42 了解typename的双重意义

template<class T>class w;
template<typename T>class w;
//两者意义相同 没有什么不同

//一般性规则:任何时候当你想要在template中指涉一个嵌套从属类型名称,就必须在它前一个位置放置关键字typename
//依赖于template的参数称为从属名称  从与名称在class中呈嵌套状,称为嵌套从属名称
template <typename C>
void print(const C& container)
{
    if(container.size() >= 2)
    {
    typename C::const_iterator iter(container.begin());//一般性依赖
    ...
}

声明template参数时,前缀关键字class和typename可互换

一般性原则使用时必须使用template。

 

 

条款 43 学习鼓励模板化基类内的名称  

可在派生类模板内通过this->指向基类模板中的名称

 

条款 44 将与参数无关的代码抽离template 

 

看不懂=-=

 

条款45 运用成员函数模板接受所有兼容类型

template <tpename T>
class SmartPtr{
public:
    template<typename U>
    SmartPtr(const SmartPtr<U> & other)
    :heldPtr(other.get()){...}   //以other的heldPtr初始化this的heldptr
    T* get() const {return heldPtr;}
    ...
private:
    T* heldPtr;
}; 

 

 

条款46 需要类型装换时请为模板定义非成员函数

template<typename T>
class Rational{
public:
    Rational(const T& numberator = 0,const T& denominator = 1);
    const T numerator() const;
    const T denominator() const;
    ...
};
template<typename T>
const Rational<T> operator * (const Rational<T>& lns,const Rational<T>& rhs)
{...}

//调用
Rational <int> oneHalf(1,2);       
Rational <int> result = oneHalf * 2;//错误,无法通过编译


template<typename T> class Rational;
template<typename T> const Rational <T> doMultiplt(const Rational<T> & lhs,
                                                    const Rational<T>& rhs);
template<typename T> class Rational{
public:    
      ....
    friend const Rational<T> operator*(const Rational<T>& lhs, const Rational<T>& rhs)
    {
    return doMultiplt(lhs,rhs);
    }
};

template<typename T> const Rational <T> doMultiplt(const Rational<T> & lhs,
                                                    const Rational<T>& rhs)
{
    return Rational<T>(lhs.numerator()* rhs.numerator(),lhs.denominator * rhs.denominator());
}

//作为一个template,doMultiply不支持也不需要支持混合式乘法,它只被operator *调用,而operator支持 混合式操作。

当我们编写class template,它所提供的 与此template相关的 函数支持 所有参数的隐式类型转换时,请将那些函数定义为 class template 内部的friend函数。

 

条款47 请使用traits classes 表现类型信息

分解迭代器相关问题-=-= 

 

条款48 认识template元编程(TMP)

//计算阶层的元模板

template<unsigned n>
struct Factorial{                    //n*n-1
    enum{ value = n * Factorial<n-1>::value};
};
template<>         //考虑特殊情况<0>值为1
struct Factorial<0>{
    enum { value = 1};
};


int main()
{
    std::count<<Factorial<5>::value;
    std::count<<Factorial<10>::value;
    return 0;
}

TMP可以将工作由运行期移往编译区,因而得以实现早期错误侦测和更高的执行效率。

 

条款49 了解 new-handler的行为

就是详细的解释了一下new 的行为

 

条款50 了解new和delete的合理替换时机

理由:

1用来检测运用上的错误。比如内存泄露

2为了强化效能

3为了收集使用上的统计数据

 

 

条款51  编写new和delete时需要固守常规

operator new 应该内含一个无穷循环,并在其中尝试分配内存,如果无法满足内存需求,就应该调用new-handler。它也应该有能力处理0bytes申请

 

条款52 写了placement new 也要写placement delete

自定义new函数要写配套,且不要无意识的遮掩了他们正常的版本

 

条款53 不要忽略编译器的警告

严肃对待编译器发出的警告信息,努力在最高警告级别下没有警告。

 

条款54 让自己熟悉包括TR1在内的所有标准程序库

TR1中添加了智能指针,一般化函数指针,以及其他组件。

 

条款55 让自己熟悉Boost

boost.org

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值