18、深入浅出MFC学习笔记,关于C++

简介: 一、一些基本概念 1、this指针 Class Crect { public: void setcolor(int color){m_color=color;} } ; 编译后为: Class Crect { public: void setcolor(int color,(Crect*)this){this.m_color=color;} } 2、如果基类和派生类都定义了“相同名称之成员函数”,那么通过对象指针调用成员函数时,到底调用哪一个函数,必须视指针的原始类型而定。

一、一些基本概念

1this指针

Class Crect
{
public:
void setcolor(int color){m_color=color;}
}  ;
编译后为:
Class Crect
{
public:
void setcolor(int color,(Crect*)this){this.m_color=color;}
}

2、如果基类和派生类都定义了“相同名称之成员函数”,那么通过对象指针调用成员函数时,到底调用哪一个函数,必须视指针的原始类型而定。而不是视指针实际所指的对象的类型所定。(没有定义虚函数)

3MFC有两个重要的虚函数:与document相关的Serialize函数和与view相关的OnDraw函数,在自己的CMyDoc,CMyView中改写这两个函数。

4、小结虚函数

1)如果你估计派生类会重新定义一个成员函数,那么你就把基类中的这个函数写成virtual

2)通过单一指令调用不同函数,就是多态Polymorphism,"ability to asume many

forms"

3)虚函数是c++语言polymorphism性质以及动态联编的关键。

4)既然抽象类中的虚函数不打算被调用,那么就把它设置成纯虚函数。

5)拥有纯虚函数者为抽象类。

6)抽象类不能产生出对象实体,但是我们可以拥有指向抽象类的指针,以便于操作抽象类的各个派生类。

7)虚函数派生下去仍是虚函数,可以不写virtual

5、每一个“内含虚函数的类”,编译器都会为它做出一个虚函数表,表中的每一个元素都指向一个虚函数的地址。此外,编译器当然会为类加上一项成员变量,是一个指向该虚函数表的指针。

wps_clip_image-29121

虚函数表的内容是依据类中的虚函数声明次序,一一填入函数指针。派生类会继承基类的虚函数表,当我们再派生类中改写了虚函数时,虚函数表就受到了影响:表中元素所指的函数地址将不再是基类的函数地址,而是派生类的函数地址。

wps_clip_image-27072

对象的起始地址就是vptr

6、如果在产生任何object之前就存取其classstatic变量,则需要设计一个static成员函数。由于static成员函数和static变量一样,可以不需要借助任何对象就可以调用,所以编译器不会为它加上一个this指针,也正因为如此,static的成员函数无法处理非static的成员变量。

7、对于全局对象,程序一开始,其构造函数就开始执行(比程序进入点更早)。程序即将结束前,其析构函数就开始执行。

对于局部对象,当对象诞生时,其构造函数被执行;当程序流程将离开该对象的存活范围(以至于对象将毁灭)时,其析构函数被执行。

对于静态(static)对象,当对象诞生时其构造函数被执行;当程序将结束时(此对象因而将遭致毁灭)其析构函数才被执行,但比全局对象的析构函数早一步执行。

对于以new方式产生出来的局部对象,当对象诞生时其构造函数被执行。析构函数则在对象被delete时执行。

8、四种不同对象的生存方式:

第一种:
void MyFunc()
{
CFoo foo;.//在堆栈(stack)之中产生foo对象 .
...
}
第二种:
void MyFunc()
{
...
CFoo* pFoo = new CFoo();//在堆 (heap)中产生foo对象 .
}
第三种:
CFoo foo;//在任何一个函数范围之外做此操作
第四种:
void MyFunc()
{
static CFoo foo;//在函数范围(scope)之内是一个静态对象
…
}

不管哪种做法,C++都会产生一个构造函数的调用。前两种情况C++在配置内存之后产生一个隐藏的构造函数调用。第三种情况需要靠startup代码帮忙。

startup代码是比main或者WinMain函数更早执行起来的代码,由c++编译器提供,能够用来处理像函数库初始化、进程信息设立、I/O stream产生等操作。

当编译器编译程序发现一个静态对象时,它会把这个对象加到一个链表中。当把控制权交给main函数之前,startup代码会快速在链表上移动,调用所有登记在案的构造函数并使用登记的参数,于是就初始化了静态对象。

第四种情况相当类似C语言中的静态局部变量,只会由一个实例产生,并且在固定的内存上(即不在stack上也不在heap上)。它的构造函数在控制权第一次转移到其声明处(也就是MyFunc第一次被调用时)被调用。

9RTTI

编译选项:/GR

typeinfo.h

typeid是一个新的重载运算子(静态的多态,拥有一种以上的形式),参数可以是类名,也可以是对象指针。返回type_info&

10MFC支持动态创建,是由一组宏(DECLARE_DYNCREATEIMPLEMENT_DYNCREATE)和类CRuntimeClass

11、异常处理

C++exception基本与Csetjmp,longjmp函数对待的东西。

12、链接器会把所有赘余的template代码删除,这在Borland链接器里头称为smart技术,其它链接器亦使用类似的技术。

参考

[1] 深入浅出MFC

目录
相关文章
|
6月前
|
C++
c++学习笔记07 结构体
C++结构体的详细学习笔记07,涵盖了结构体的定义、使用、数组、指针、嵌套、与函数的交互以及在结构体中使用const的示例和解释。
62 0
|
5月前
|
安全 C语言 C++
C++学习笔记
C++学习笔记
|
6月前
|
算法 C++
c++学习笔记04 数组
这篇文章是C++学习笔记4,主题是数组。
58 4
|
6月前
|
C++
【学习笔记】【C/C++】 c++字面值常量
【学习笔记】【C/C++】 c++字面值常量
63 1
|
6月前
|
存储 C++
c++学习笔记05 函数
C++函数使用的详细学习笔记05,包括函数的基本格式、值传递、函数声明、以及如何在不同文件中组织函数代码的示例和技巧。
46 0
c++学习笔记05 函数
|
6月前
|
编译器 C++
【C/C++学习笔记】C++声明与定义以及头文件与源文件的用途
【C/C++学习笔记】C++声明与定义以及头文件与源文件的用途
89 0
|
6月前
|
存储 C++
【C/C++学习笔记】string 类型的输入操作符和 getline 函数分别如何处理空白字符
【C/C++学习笔记】string 类型的输入操作符和 getline 函数分别如何处理空白字符
71 0
|
6月前
|
C++
c++学习笔记09 引用
C++引用的详细学习笔记,解释了引用的概念、语法、使用注意事项以及引用与变量的关系。
49 0
|
6月前
|
存储 程序员 编译器
c++学习笔记08 内存分区、new和delete的用法
C++内存管理的学习笔记08,介绍了内存分区的概念,包括代码区、全局区、堆区和栈区,以及如何在堆区使用`new`和`delete`进行内存分配和释放。
72 0
|
6月前
|
存储 C++
c++学习笔记06 指针
C++指针的详细学习笔记06,涵盖了指针的定义、使用、内存占用、空指针和野指针的概念,以及指针与数组、函数的关系和使用技巧。
44 0