10.扩充:类模板,函数模板及其他
1.static:
1.在数据或函数前加static关键字,则变为静态函数/数据。 2.一个成员函数要处理很多个数据,需要靠某个东西告诉他处理谁,就是this pointer。来告诉他处理从c1、c2、c3。成员函数有一个隐藏的this pointer参数。(右下角黄色部分可写可不写,real后面的()里面一定不能写) 3.加上static之后,这个数据/函数就不属于这个对象了,跟这个对象脱离。 4.静态函数没有this pointer参数,因此不能直接处理普通的对象,只能处理静态数据。 1.这个例子中,利率mrate是静态数据,set_rate是静态函数。 2.静态函数set_rate只能处理静态数据。 3.静态函数可以通过对象object来调用,也可以通过class name来调用。 4.静态成员:类内声明,类外初始化 1.构造函数放在private中,不想让外界创建。 2.设计一个静态函数,来返回唯一的那一份,这个静态函数是外界取得这一份的唯一方法。 3.调用这个静态函数之后,才开始创建这唯一的一份。 1.cout是一种ostream。 2.设计了很多种<<的操作符重载
2.类模板:
1.使用T来代替某种类型,类模板。 2.使用的时候,<>中写明类型,编译器就会把T全部替换为这种类型。 1.这里面的min,比较的类型用T来表示。 2.这样比较的时候,<符号就会使用T类型中重载的<符号来进行。 3.用的时候不需要用<>绑定类型,编译器会根据传进去的对象类型自动绑定T类型。
3.namespace:
11.组合与继承
1.复合: 1.表示这个class queue中,有一个这种sequence类东西。 2.这个sequence是deque 3.queue里面所有的功能,都是调用c的功能来完成的。 1.queue中有deque,deque的源代码中,还有另一个复合,Itr。 2.从内存的角度看,queue占用40字节。 1.左边拥有右边。 2.复合情况下的构造函数,由内而外,析构函数,由外而内。代码中红色的部分,是编译器来完成的。编译器会调用内部的默认的构造函数或析构函数。如果不希望调用默认的,那么就需要自己写代码。
2.委托: 1.引用方式的复合,即左边has a右边类的指针。 2.即可以通过该指针,把任务委托给右边的类。 3.复合中,内部和外部是一起出现的,即调用二者的构造函数;而委托的话,因为是指针,是不同步的,当需要右边的时候,才创建这个。 4.应用实例:右面的类为具体的实现,左边只是调用的接口。
3.继承: 1.黄的的一行为使用public继承的语法,表示继承_List_node_base类。 2.继承,表示is-a,是一种。 3.父类的数据会被完整继承下来。 子类拥有自己的以及父类的数据。 4.继承和虚函数搭配是关键 1.子类的对象中有父类的成分。 2.构造时,先调用父类的构造函数,然后再调用自己的。 3.析构时,先析构自己,然后析构父类的。 4.编译器会自动完成。
12.虚函数与多态
1.搭配虚函数来完成继承。 2.在任何成员函数之前加上virtual关键字,即为虚函数。 3.子类可以调用父类的数据和函数,即继承了函数(实际上是继承了函数的调用权)。 4.非虚函数,是不希望子类重新定义(override)的函数。 5.虚函数,希望子类重新定义它,且已有默认定义。 6.纯虚函数,希望子类重新定义它,且目前没有默认定义,一定要去定义。即函数定义后面直接=0。 7.上图中,定义了一个父类shape,其中定义了几种成员函数。objectID是非虚函数,不需要重新定义。error是虚函数,有默认定义,可以重新定义。draw函数是纯虚函数,没有默认定义,必须要子类来重新定义。 1.父类中其他可以通用,读文件这个函数Serialize设置为虚函数,需要override。 2.我们定义一个读文档的类,那么serialize函数就要override成读文档的函数。 3.调用serialize时,通过隐藏的this pointer来调用,因为myDoc.OnFileOpen,因此this就是myDoc,因此调用的是我们override之后的serialize函数。 4.这就是设计模式,template method 复合+继承: 1.继承+复合。 2.构造函数,首先调用父类的构造函数,然后调用复合的构造函数,然后调用自己的构造函数。 3.析构函数相反。
委托+继承:
1.observer来观察subject的数据。一个subject数据可以有多个observer来观察。observer是一个父类,可以定义子类来继承,因此可以有不同的观察方法。 2.当数据改变的时候,observer也需要更新,即notify函数,来将目前所有的observer更新。
13.委托相关设计
1.设计一种类似窗口的类,窗口中可以有其他窗口,窗口中有其他类对象。 2.primitive是对象个体,composite是一种窗口容器,特殊点在于放的可能是其他对象,也可能是窗口。 3.因此把primitive和composite都继承自component,然后composite容器存放的是指向component对象的指针即可(因为vector里面只能放相同大小的东西,所以放指针)。这样composite中存放的可能是窗口,也可能是对象。 4.这就是设计模式:composite。 5.component中add是虚函数,不能是纯虚函数,因为primitive无法override add函数。composite需要override add函数,使得容器可以存放窗口,也可以存放对象。 1.想要创建未来才会出现的子类(下面是派生的子类)。 2.子类中,安排一个静态对象(_LAST),然后把它放到父类之前开辟出的一个空间中,这样父类就可以看到新创建的子类。 3.这个静态对象创建的时候,调用自己私有的构造函数,调用addPrototype,这样就把自己放到了父类中。 4.子类中,还需要准备一个clone函数。这样父类就可以通过调用clone方法来创建这种子类的副本。 静态变量要到本体外部去定义,这样才是分配内存。
|