云题海 - 专业文章范例文档资料分享平台

当前位置:首页 > effectiveC++

effectiveC++

  • 62 次阅读
  • 3 次下载
  • 2025/5/4 22:58:13

class A{};

voiddel_func(A *a){

cout<<\删|?除y对?象¨?\<

void test(){

A *a = new A;

shared_ptrpa(a,del_func); }

NO15 在资源类中提供对原始资源的访问

1、显示转换,.get() -> *等等: class A{ public:

A():a(7){}

void display(){cout<<\值|ì:êo \<

void test(){

A *a = new A;

shared_ptrpa(a);

cout<display();

cout<<(*pa).a<

2、隐式转换 class DB{ public:

DB():name(\){} string name; };

classDBManager{ public:

DBManager(DB &d):data(d) {} operator DB() const{ return data; }

DB get(){return data;} private : DB data; };

voidprint_db(DB d){ cout<

void test(){ DB d;

DBManagerdbm(d);

print_db(dbm.get()); //显示转换

print_db(dbm); //通过重载运算符()的隐式转换

print_db(dbm.operator DB()); //和上面一句是等价的 }

NO16 delete 与delete[]

1、删除数组指针要用 delete [] 2、注意typedef导致的混淆

typedef string AddressLines[4]; string* pal=new AddressLines; //等价于string *pal = new string[4]; delete [] pal

//但是如果没有看到typedf语句的话很容易把pal当成一个string的指针,从而写出了:delete pal;

NO17 以独立语句将new对象置入智能指针

class Widget{}; intget_priority(){ staticinti=0; returni++; }

voidprocessWidget(std::tr1::shared_ptrpw,int priority){ //do something; }

void test(){

//错误做法:因为编译器并没有确定processWidget前后两个参数产生顺序,如果

//get_priority()调用在new widget和构造shared_ptr直接发送异常会导致内存泄漏。 //processWidget(std::tr1::shared_ptr(new Widget),get_priority()); //正确做法:把构造shared_ptr的语句放到函数调用外面。 shared_ptr pw (new Widget); processWidget(pw,get_priority()); }

NO18 让接口容易被正确使用

1、导入新类型以预防客户端错误 2、避免与内置类型不一致

eg:重载operator*()需要加上修饰符const,以使得a*b=c不合法

3、使用shared_ptr,直接返回包装好的指针(且同时制定删除器而不是由用户对shared_ptr进行删除)

NO19略

NO20 用const的引用传递代替值传递

1、值传递的函数使用的是传递过来对象的副本,所以函数不能能改变他,因此换做引用传递时必须保证是const XXX& x. 2、引用传递还可以防止对象切割导致的问题:

class People{

public: virtualvoid speak()const {cout<<\<

class Chinese: public People{

public: void speak() const {cout<<\我是中国人\<

//Chinese p func(p)只能输出\people\因为根据实参构造形参时把base class //以外的部分切割了。 voidfunc(People p){ p.speak(); }

//可以正常运行

voidfunc(const People &p){ p.speak(); }

当然了,通过这种方法是调用的必须是const成员函数(因为不管事值传递还是const引用传递都不可能改变原来的对象)。

3、pass-by-value成本不高的集中情况:内置类型、STL的迭代器、函数对象

NO21 必须返回对象时别妄想返回其引用

几种错误情况: 1、Studen& get(){

Student s(“name”,13);

return s; }

这样返回的引用指向的student在函数返回时就已经被析构了

即使函数内设置static Student也有问题(多线程安全性、两次get()所得对象无法比较)

2、Student& get(){

Student *s = new Student(“name”,13);

return s;

}

这样删除Student对象变得很困难。尤其是x*y*z这种隐藏的指针根本无法删除。

NO22 将成员变量声明为private

1、提高封装性,改变实现后用户代码可以保存不变

2、其实protected和public一样会带来封装性的严重下降

NO23 用非成员函数、非友元替换成员函数

1、no-member相比于member函数可以使更少的代码访问类的private成员 2、采用no-member函数,并将不同作用的non-member函数分布在不同的头文件中会有效提高扩展性:

NO24 若参数均需类型转换,改用non-member函数

1、

class Rational{ public:

Rational(int numerator=0,int denominator=1):

nu(numerator),de(denominator){}

int numerator() const {return nu;} int denominator() const{return de;} private: int nu; int de; };

若Rational中增加一个成员函数operator* :

const Rational opeartor(const Rational &rhs){ return Rational(nu*rhs.nu,de*rhs.de); }

则:

Rational r4 =r*2; Rational r5 = 2*r;

//正确 //错误

这是因为:只有当参数被列于参数列时,他才是隐式转换的合格参与者,因此r*2中的2被当成了operator*(const Rational &)中的参数。而2*r中的2不在参数列表中。

2、正确做法:改成non-member函数:

const Rational operator*(const Rational &lhs,const Rational &rhs){

Rational

r(lhs.numerator()*rhs.numerator(),lhs.denominator()*rhs.denominator());

return r; }

此时2*r也可以正确运行

tips:这个non-member函数不需要作为友元,因为他可以通过函数访问nu,de.

搜索更多关于: effectiveC++ 的文档
  • 收藏
  • 违规举报
  • 版权认领
下载文档10.00 元 加入VIP免费下载
推荐下载
本文作者:...

共分享92篇相关文档

文档简介:

class A{}; voiddel_func(A *a){ cout<<\删|?除y对?象¨?\< *等等: class A{ public: A():a(7){} void display(){cout<<\值|ì:êo \<

× 游客快捷下载通道(下载后可以自由复制和排版)
单篇付费下载
限时特价:10 元/份 原价:20元
VIP包月下载
特价:29 元/月 原价:99元
低至 0.3 元/份 每月下载150
全站内容免费自由复制
VIP包月下载
特价:29 元/月 原价:99元
低至 0.3 元/份 每月下载150
全站内容免费自由复制
注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信:fanwen365 QQ:370150219
Copyright © 云题海 All Rights Reserved. 苏ICP备16052595号-3 网站地图 客服QQ:370150219 邮箱:370150219@qq.com