补充自己的。
转自:http://blog.csdn.net/ysu108/article/details/9853963#t0
在VC下new之后在检查是否为NULL。标准C++规定new一个对象时如果分配内存失败就应抛出一个std::bad_alloc异常,如果不希望抛出异常而仅仅传回一个NULL指针,可以用new的无异常版本:new(nothrow)。在VC6.0中默认是不会抛出异常的,而是会返回一个NULL。但是在linux下编译可能会抛出异常。这个new失败分两种情况来处理,一、如果是内存不够那么这种情况抛出还是不抛出异常其实已经无所谓了。二、如果分配空间ok但是构造函数中出现问题,这个时候就比较麻烦了,所以对于复杂的对象,比如要启动一个线程,那么最好线程启动函数单独写一个init函数,而不是放在构造函数中,构造函数中只放那些简单对象的初始化。注意这里的init是负责“可能出现错误或异常”的处理,并不是说这个对象成员变量很多,如果成员变量很多可以写成单独的一个函数init,但目的是抽离复杂的初始化,让程序可扩展比较容易读。
这个是为了防止内存泄露,但是有的时候实现拷贝构造函数和赋值函数很困难而且不会用到的时候,可以声明这些函数,注意是声明为private,但不实现它,这样在有人误用,编译器会警告的。
这个主要优点两个:1.如果有继承关系,使用初始化列表可能少调用一次类成员变量的构造函数,直接调用拷贝构造函数。2.可以满足const和引用成员初始化的要求。(同时可以有一定扩展性,可以适应原来的非const变成const)。如果参数很多,初始化列表太长不方便阅读,可以单独抽象出一个init函数。
首先,要明确一点“类成员是按照它们在类里被声明的顺序进行初始化的,和它们在成员初始化列表中列出的顺序没一点关系”,因为如果不这样设计的话,类析构的时候与初始化顺序相反,如果与初始化列表中顺序一致,那么类就要有一种机制来负责记录初始化的顺序,显然是没有必要的。初始化顺序与在构造函数中的顺序就更没有关系了,在进入构造函数中的时候就已经为所有的成员变量分配好了,在构造函数中做的其实是赋值或者说拷贝。没有关系为什么要相同呢?这是一种编程习惯,如果你确信相同,那么就可以知道参数构造的逻辑(有些参数是与顺序相关的,所以在设计类中参数顺序的时候也要注意),对与程序员来说就会多知道一层逻辑,少一点错误。
子类的删除的时候会自动调用父类的析构函数——这句话有歧义的,这是一种机制和虚函数没有关系,但是如果是用基类的指针来析构子类对象就不会调用子类析构函数,这个时候和虚函数就有关系了。
c++的设计者bjarne stroustrup下了很大的功夫想使用户自定义类型尽可能地和固定类型的工作方式相似。这就是为什么你可以重载运算符,写类型转换函数(见条款m5),控制赋值和拷贝构造函数,等等。如果不返回*this的引用,它妨碍了连续(链式)赋值操作.
包括基类的成员变量。
这个不用在多说了。
这个,单一职责。
这个情况遇见很少,只适用于<<和>>操作符,如果他们是成员函数,那么调用的时候有c<<cout(类需要在<<左边),虽然和法但是平常不是这么用的。operator>>和operator<<决不能是成员函数。如果f是operator>>或operator<<,让f成为非成员函数。如果f还需要访问c的非公有成员,让f成为c的友元函数。只有非成员函数对最左边的参数进行类型转换。如果f需要对最左边的参数进行类型转换,让f成为非成员函数。如果f还需要访问c的非公有成员,让f成为c的友元函数。
很少有人把数据直接暴露给用户,也不安全。
mutable类型的成员变量,可以在const成员函数被修改。
在传类类型的对象时要注意。引用几乎都是通过指针来实现的,所以通过引用传递对象实际上是传递指针。因此,如果是一个很小的对象——例如int——传值实际上会比传引用更高效。
两个函数都必须对新对象赋一个初值。这会导致在两个构造函数里出现重复代码,所以要写一个“包含有两个构造函数公共代码”的私有成员函数init来解决这个问题。这个方法——在重载函数中调用一个“为重载函数完成某些功能”的公共的底层函数——很值得牢记,因为它经常有用。
void f(int x);
void
f(char*ps);
在调用f(0)的时候可能会引起歧义,所以,不要试图去重载指针和数字类型。
在类的继承中常会发生。
一般都是赋值函数和拷贝构造函数,为防止用户误用,可以把它们定义为私有的。赋值和拷贝构造函数具有行为上的相似性,这意味着几乎任何时候当你想禁止它们其中的一个时,就也要禁止另外一个。
大型程序很重要。
可以返回一个const char * getP() const;需要该值得指针也必须是一个const char *。
意思是返回了一个私有成员的指针或引用,这样就破坏了访问限制。返回值是某个访问级较低的成员的指针或引用。但同时,你又不想牺牲private和protected为你提供的访问限制。这种情况下,你可以通过返回指向const对象的指针或引用来达到两全其美的效果。
代理模式也可以这么用~
一般来说类的构造函数与析构函数不要定义为内联函数,他们很可能被父类扩展。一个程序往往花80%的时间来执行程序中20%的代码。这是一条很重要的定律,因为它提醒你,作为程序员的一个很重要的目标,就是找出这20%能够真正提高整个程序性能的代码。你可以选择内联你的函数,或者没必要就不内联,但这些选择只有作用在"正确"的函数上才有意义。一旦找出了程序中那些重要的函数,以及那些内联后可以确实提高程序性能的函数(这些函数本身依赖于所在系统的体系结构),就要毫不犹豫地声明为inline。同时,要注意代码膨胀带来的问题。
在类内的成员变量为类类型的时候,可以使用类类型的指针,然后再头文件中声明这个类即可,不用包含这个类的头文件,而在实现中包含,这样依赖性降低,只要类类型的成员变量接口不变就不用编译。为什么必须是指针呢?因为编译器编译的时候需要知道类型的大小,像int,编译器知道为4。编译器也可以不知道,但是只是为了安全,或者说达到类型安全的一个级别吧才需要知道。
共有继承是强侵入的,继承的子类有父类的所有的方法。这可能导致子类(或者孙子类)有不希望的行为,所以多用组合,少用继承。
一般,接口继承是为了实现多太,实现继承是为了代码服用
这个语法上虽然合法,但是很容易造成接口的混乱,要重定义使用虚函数,实现多态。
缺省参数是静态绑定,如果基类中默认参数为Va,子类中重定义为Vb,涉及到多态的时候可能会调用子类函数,却使用基类默认的参数Va。C++这样做是为了提高效率,否则要一种机制来实现参数的动态绑定。
也就是使用dynamic_cast,首先这个转换是效率很低的,指针转换失败为NULL,引用好像是抛出异常。最好可以使用虚函数,非到万不得已,不要使用这个。
也就产生依赖,多用组合少用继承。
通常情况下使用模板都会涉及到算法,当类型改变的时候却不影响使用到的这个类的行为,那么就可以使用模板。例如STL中大量使用模板,同常是对某一个类型的存储,增加删除等操作,在操作的过程中一般不会用到对这个类型特定的接口,使用到也就简单的new,delete等。而使用继承比较常见于面向对象的设计,这一组类通常有着相同的接口。简单来说使用模板一般是会用到算法,而使用继承通常是为了有不同的行为。
私有继承意味着"用...来实现"这一事实会给带来一点混淆,"分层"也就是组合也具有相同的含义。怎么在二者之间进行选择呢?答案很简单:尽可能地使用分层,必须时才使用私有继承。什么时候必须呢?这往往是指有保护成员和/或虚函数介入的时候。“用...实现”的类不想被随便的实例化(构造函数被定义为保护或私有)(一般这个类如果实例化安全性很差,例如有void*这种类型),这个时候可以使用私有继承。还有就是有虚函数的时候。
多继承可能导致二义性,使用过程中不要出现钻石型继承和虚函数歧义的情况,使用多继承可以使得代码服用,但是不能只是为了“使用一个类”而无限制的私有继承类,有的时候为了逻辑清晰,可以增加一个类来代替共有继承,使得代码容易维护。
公有继承和 "是一个" 的等价性,以及非虚成员函数和 "特殊性上的不变性" 的等价性,是C++构件如何和设计思想相对应的例子。下面的列表总结了这些对应关系中最重要的几个。
· 共同的基类意味着共同的特性。如果类D1和类D2都把类B声明为基类,D1和D2将从B继承共同的数据成员和/或共同的成员函数。见条款43。
· 公有继承意味着 "是一个"。如果类D公有继承于类B,类型D的每一个对象也是一个类型B的对象,但反过来不成立。见条款35。
· 私有继承意味着 "用...来实现"。如果类D私有继承于类B,类型D的对象只不过是用类型B的对象来实现而已;类型B和类型D的对象之间不存在概念上的关系。见条款42。
· 分层意味着 "有一个" 或 "用...来实现"。如果类A包含一个类型B的数据成员,类型A的对象要么具有一个类型为B的部件,要么在实现中使用了类型B的对象。见条款40。
下面的对应关系只适用于公有继承的情况:
· 纯虚函数意味着仅仅继承函数的接口。如果类C声明了一个纯虚函数mf,C的子类必须继承mf的接口,C的具体子类必须为之提供它们自己的实现。见条款36。
· 简单虚函数意味着继承函数的接口加上一个缺省实现。如果类C声明了一个简单(非纯)虚函数mf,C的子类必爰坛衜f的接口;如果需要的话,还可以继承一个缺省实现。见条款36。
· 非虚函数意味着继承函数的接口加上一个强制实现。如果类C声明了一个非虚函数mf,C的子类必须同时继承mf的接口和实现。实际上,mf定义了C的 "特殊性上的不变性"。见条款36。
转:Effective c + + notes,布布扣,bubuko.com
原文:http://www.cnblogs.com/kira2will/p/3594810.html