effective c++ 总结

一、尽可能使用const:
1、声明常量:
const double AspectRatio=1.653
const char *const name=”fm”
const std::string name(“fm”)
2、const修饰成员函数:const修饰成员函数,相当于const classname * const this;那么,这个对象的成员变量的内容在这个const函数中是不可改变的。若想改变某个成员变量,可在成员变量前使用关键字 mutable。
3、const可以作用在常量、函数参数、函数返回值、成员函数的this指针。
二、要先初始化对象,然后再使用。
1、常量、变量初始化
int x=0;
double y;
std::cin>>y;
const char * p =”c plus plus ! “;
2、构造函数(列表)初始化
Book::Book(int a,int b): a(i),b(j){ }
3、拒绝对象拷贝:在类中定义 : private: Box& operator=(const Box&);
三、构造函数、拷贝赋值、析构函数
1、编译器默认为一个类生成:拷贝构造函数、析构函数、拷贝赋值运算符
例如:
class Empty{};
编译后的Empty:
class Empty{
Empty(); //默认构造函数; 若重写构造函数,则覆盖默认构造函数。
Empty(const Empty&); //拷贝构造函数
~Empty(); //析构函数
Empty& operator=(const Empty&); //拷贝赋值运算符
};
2、阻止编译器生成拷贝赋值运算符、拷贝构造函数:
(1)
class HomeForsale{
private:
HomeForsale(const HomeForsale&);
HomeForsale& operator=(const HomeForsale&);
};
(2)
class Uncopyable{
protected:
Uncopyable(){}
~Uncopyable(){}
private:
Uncopyable(const Uncopyable&);
Uncopyable& operator=(const Uncopyable&);
};
class HomeForsale:private Uncopyable{
………
};
3、
若一个类作为base class,这个类应使用虚析构函数。
若这个base class是标准库中的类,则无法使用虚析构函数。
若一个类不是作为base class ,这个类不应使用虚析构函数。
4、析构函数可能发生异常:
解决方法:
~DBcon(){
try{db.close();}
catch(..){
std::abort();
}
}
5、构造函数、析构函数不要调用虚函数
6、令operator+= 重载运算符:return *this;
7、重写派生类的copy构造函数:
class Customer{ };
class PriorityCustomer:public Customer{
public:
PriorityCustomer(const PriorityCustomer& rhs):Customer(rhs),priority(rhs.priority)
{

} //先copy基类成分,再copy派生类成分。
PriorityCustomer& operator=(const PriorityCustomer& rhs)
{
Customer::operator=(rhs);
priority=rhs.priority;
return *this;
}//先copy基类成分,再copy派生类成分。
private:
int priority;
};
四、资源管理
1、
class Investment{ };
Investment* createInvestment(); // class factory
int days (const Investment * pi); //对象处理函数
void f(){
Investment *p=createInvestment();
….
delete p; //不好,若…抛出异常,无法释放内存。
//使用智能指针:
shared_ptr<Investment> p(createInvestment());
int d=days(p.get()); //智能指针转化为普通指针
}
2、
typedef std::string Address[4];
std::string *s=new Address;
delete [ ]s; //delete 数组加[ ]
五、设计与声明:
1、以void fun(const Student& s) 代替 void fun(Student s) ,因为Student s 需要调用Student类的copy构造函数。
六、实现:
1、

std::string encryptPassword(const std::string& password){
    using namespace std;
    // string encrypted; 在此处定义,若if语句抛出异常,可能会付出调用string构造函数、析构函数的代价
    if(password.length()<Minpassword){
    throw logic_error("password is too short!");
    }
    string encrypted;  //尽可能延后定义encrypted
    //string encrypted(password);  调用copy构造函数初始化
    ...
    return encrypted;
}

七、public、private 继承

class Base{
public: 
   int pub_param;
protected:
   int pro_param;
private:
   int pri_param;
};
class pub_derived:public Base{
int f(){return pub_param;}
int fun(){return pro_param;}
};
class pri_derived:private Base{
int f(){return pub_param;}  //错误,私有继承不能访问public成员
int fun(){return pro_param;}
};
Base *bp=new pri_derived(); //错误,私有继承不能赋值给基类

八、使用using,让Base中的被覆盖函数在Derived类中可见:

class Base{
privateint x;
public:
   virtual void mf1()=0;
   virtual void mf1(int);
};
class Derived:publc Base{
//添加Base的mf1函数:
using Base::mf1;
virtual void mf1(); //覆盖了Base 的mf1()、mf1(int)
};
Derived d;
int x;
d.mf1();   //调用derived::mf1()
d.mf1(x);  //错误,mf1(int)被覆盖(using Base::mf1;,正确)

九、类模板、泛型编程
1、typename必须作为嵌套从属类型的前缀词:

template<typename C>
void printed(const C& container) //不是嵌套从属类型,不需要加typename
{
   if(container.size()>=2)
    typename C::const_iterator iter(container.begin()); //c::const_iterator是嵌套从属类型,需要加typename告诉编译器这是一个类型。
   ...

}
例外情况:
template<typename T>
class Derived::public Base<T>::Nested{
public:
explicit Derived(int x):Base<T>Nested(x){
typename Base<T>::Nested temp;
}  //继承基类列表、函数初始化列表不能使用typename

};

2、derived class templates调用base class templates中的成员:

template<typename Company>
class MsgSender{
public:
void sendClear(const MsgSender& info){...}
void sendSecret(const MsgSender& info){..}
};
template<typename Company>
class LoggingMsgSender:public MsgSender<Company>{
public:
void sendClearMsg(const MsgInfo& info)
 {
    sendClear(info); //不能直接调用base class template的函数
    //若要调用有三种方法:
    (1)this->sendClear(info);
    (2)using MsgSender<Company>::sendClear;
    (3)MsgSender<Company>::sendClear(info);
 }
};

3、成员函数模板:

template<class T>
class shared_ptr{
public:
shared_ptr(shared_ptr const& r);
template<class Y>
shared_ptr(shared_ptr<Y> const& r); //泛化拷贝构造函数

template<class Y>
shared_ptr(weak_ptr<Y> const& r);//泛化拷贝构造函数,用于兼容其他类型

shared_ptr& operator=( shared_ptr const& r); 
template<class Y>
shared_ptr& operator=( shared_ptr<Y> const& r);//泛化拷贝赋值运算符
};
//当声明了泛化拷贝构造函数、泛化拷贝赋值运算符后,还要声明正常的拷贝赋值运算符、拷贝构造函数

4、用到模板类的非成员函数涉及到类型转换时,要声明为友元

template<typename T>
class Rational{
public:
Rational(const T& numerator=0,const T& denominator=1);
const T numerator() const;
const T denominator() const;
...
friend const Rational opreator*(const Rational& lhs,const Rational& rhs)
{return Rational(lhs.numerator*rhs.numerator,lhs.denominator*rhs.denominator);}  //编译器可以得知T的类型(在模板类中,Rational可以代替Rational<T>)

};
template<typename T>
const Rational<T> opreator*(const Rational<T>& lhs,const Rational<T>& rhs)
{...} //相当于辅助函数

Rational<int> onehalf;
Rational<int> result=onehalf*2 //不能通过编译,编译器不知道T的类型。
//要添加友元

十、定制new、delete

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值