Effective C++读书笔记03
2012-03-28
1、避免写一个成员函数,传回一个非const型指针或引用,并指向较低存取层的member
Class B
{
private :A a;
};//则a就是较低存取层的成员(即类成员变量,A类的成员变量a)
比如:
Class B
{
public : A &func() {return a;}
private: A a;
};//若进行如下调用 B b=new B();
A &temp=b.fun();
则可通过temp任意读写b.a,即b.a不再是private ,而是public
指针同上
2、不要传回局部引用或以new获得的指针所指的对象
(1)传回引用
Time &add(Time a,Time b)
{
Time c=a+b; return c;
}//当程序返回时,即遇到后大括号时,C被销毁(自动析构),引用不再指向有效对象,很危险
(2)传回new获得的指针
Time &add(Time a,Time b)
{
Time *p=new Time(…);
return *p;
}//则必须由使用者进行delete,若忘记delete,则内存泄露,同样危险
3、string temp(“hello”); string temp; temp=”hello”;
左侧通过复制构造函数进行初始化,成本只有一次函数调用
右侧先用默认构造函数进行初始化,再赋值,效率低
4、纯纯虚函数 virtual void func()=0;
声明一个纯虚函数的目的是为了让自己只继承接口(子类自己实现)
声明一个(非纯)虚函数的目的是为了让子类继承该函数的接口和缺省行为
即,可以自己写一个实现,如果不写,可以使用基类的缺省版本
声明非虚拟函数是让子类继承接口和实现
5、无论什么情况下都不应该重新定义一个继承而来的非虚拟函数(即重写)
例:D x;
B *pb=&x; pb->func();
D *pd=&x; pd->func();
若func为virtual,则为动态绑定,不管通过pb or pd,对func调用都会导致调用D::func,因为pb,pd指向的都是一个D对象——正确版
若func为非virtual,则B::func和D::func为静态绑定,则因为pb是B类型指针,即使指向D类,依然用B::func(不会依据指向对象的类型而执行函数)
难以理解的行为
∴非virtual不该重新定义(不该重写)