关闭

2.C++的重要性质(深入浅出MFC之读书笔记)

标签: mfc读书编译器classfunctiondelete
87人阅读 评论(0) 收藏 举报
分类:

this指针:

类的每一个成员函数(非static)都带一个隐藏参数this指针。

派生类对象可以赋给基类对象,但反过来不行,如果一定需要的话就需要使用指针做强制显示转型。

如果以一个“基类之指针”指向“派生类之对象”,那么经由该指针只能调用基类所定义的参数;如果以一个“派生类之指针”指向“基类之对象”,必须做明显的转型操作,不建议使用;如果基类和派生类都定义了“相同名称之成员函数”,那么通过对象指针调用成员函数时,到底调用哪一个函数,必须视该指针的原始类型而定,而不是视指针实际所指的对象类型而定,与第一点相同。

MFC有两个十分重要的虚拟函数:与document有关的Serialize函数和与view有关的OnDraw函数。

纯虚函数不需要定义其实际操作,它的存在只是为了在派生类中被重新定义。只要是拥有纯虚函数的类就是一个抽象类,它是不能够被实例化的,也就是说不能根据它产生一个对象。虚函数派生下去仍为虚函数,且可以省略virtual关键字。

每一个“内含虚函数的类”,编译器都会为它做出一个虚函数表,表中的每个元素都指向一个虚函数的地址,此外,编译器当然也会为类加上一项成员变量,是一个指向该虚函数表的指针(常被称为vptr)。每一个由此类派生出来的对象都有这么一个vptr。当我们通过这个对象调用虚函数时,事实上是通过vptr找到虚函数表,再找出虚函数的真实地址。当我们在派生类中改写虚函数时,虚函数表就受到了影响:表中元素所指的函数地址将不再是基类的函数地址,而是派生类的函数地址。

class CMyDoc::public CDocument

CMyDoc mydoc;

((CDocument)mydoc).fun();

上述调用中调用的将是基类CDocument中的函数,因为派生类对象通常都比基类对象大(指内存空间),那么向上强制转型将会造成对象的内容被切割。

静态(static)成员变量不属于对象的一部分,而是类的一部分,所以程序可以在还没有诞生任何对象的时候就处理此种成员变量,但首先必须初始化它。不要把static成员变量的初始化安排在类的构造函数中,因为构造函数可能被一再地调用,应该在应用程序文件中,类以为的位置设定初值。设定static成员变量初值时,不受任何存取权限的束缚。注意static成员变量的类型也出现在初值设定语句中,因为这是一个初值设定操作而不是赋值操作。如果希望在产生任何对象之前就存取其类的private static成员变量,则必须设计一个static成员函数。由于static成员函数不需要借助任何对象就可以被调用执行,所以编译器不会为它暗加一个this指针。也因为如此,static成员函数无法处理类之中的non-static成员变量。

new相比于malloc不但配置对象所需的内存空间,同时会引发构造函数的执行。一个有着层次结构的类群组,当派生类的对象诞生之时,构造函数的执行是由最基类至最尾端派生类;当对象要毁灭之前,析构函数的执行则是反其道而行。

对于全局对象,程序一开始,其构造函数就先被执行(比程序进入点更早);程序即将结束前其析构函数被执行。对于局部对象,当对象诞生时,其构造函数被执行;当程序流程将离开该对象的存活范围(以至于对象将毁灭)时,其析构函数被执行。对于静态对象,当对象诞生时构造函数被执行;当程序将结束时(此对象因而将遭致毁灭)其析构函数才被执行,但比全局对象的析构函数早一步执行。对于以new放生产生出来的对象,当对象诞生时期构造函数被执行,析构函数则在对象被delete时执行。

静态全局对象的构造函数调用操作必须依靠startup码帮忙,startup码是更早于程序进入点(main或winmain)执行起来的码,由C++编译器提供被链接到程序中。当编译器编译程序时,发现一个静态对象时,它会把这个对象加到一个链表之中,它还加上一个指针,指向对象之构造函数及其参数(如果有的话)。把控制权交给程序进入点之前,startup码就会快速在该链表上移动,调用所有等级在案的构造函数并使用登记在案的参数,于是就初始化了静态对象。

在程序执行过程中知道某个对象属于哪一种类在C++中称为执行期类型信息(Runtime Type Information,RTTI)的能力。

C++的template有两种,分别针对function和class。

Template Functions:

template <class T>// T是一种类型,而此类型将在调用此函数时才给予;

T function(T a,int b)

Template Classes:

template <class T>

class CThree

{

public:

CThree(T t1,T t2,T t3);

T Min();

T Max();

private:

T a,b,c;

};

template <class T>

T CThree<T>::Min()

{

T minab=a<b?a:b;

return minab<c?minab:c;

}

注意每一个成员函数前都要加上template<class T>,而且类名应该使用CThree<T>。

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:1049次
    • 积分:37
    • 等级:
    • 排名:千里之外
    • 原创:3篇
    • 转载:0篇
    • 译文:0篇
    • 评论:0条
    文章分类
    文章存档