第55课 经典问题解析(四)

关于动态内存分配:

 

 

new Test共完成两步:

1、申请堆空间

2、在申请的堆空间上调用构造函数

示例程序:

 

 第18行申请了内存空间,然后在申请的内存空间上调用了构造函数。

而第19行仅仅是申请了内存空间。

面向对象中尽量使用new。

new是C++语言的一部分。

delete:

 

 第25行的delete执行了析构函数,并且释放了内存空间。

第26行仅仅释放了内存空间。

new申请的内存要用delete释放,千万不要用free释放。因为用free释放时仅仅会释放内存,但是不会执行析构函数。

delete一个对象时会先调用析构函数。

malloc申请的内存,也不要用delete释放。有可能产生bug。

 

 

 

 关于虚函数:

 

 

在构造函数执行结束之后,虚函数表指针才会被正确初始化,因此,执行构造函数时虚函数表指针还是随机值,所以,构造函数不能成为虚函数。

析构函数在对象销毁之前被调用,因此,析构函数是可以成为虚函数的。

实验:

 

 父类和子类的析构函数都没有定义成虚函数。delete指针p时只调用了父类的析构函数,没有调用子类的析构函数。

当析构函数没有声明为虚函数时,编译器直接根据p的类型来决定调用哪个析构函数。

将析构函数声明为虚函数,执行结果如下:

这时编译器会根据p指针指向的实际类型来决定调用哪些析构函数,可以看到先调用子类的析构函数又调用父类的析构函数。

在工程中将一个类作为父类时,习惯性的将析构函数声明为虚函数。否则有可能 产生内存泄漏,因为有可能子类的析构函数调用不到。

 

 

 

 

在构造函数中调用虚函数或者在析构函数中调用虚函数,编译器怎么处理呢?

在这两种情况下调用的虚函数必然是当前类中定义的版本。

 

 实验:

 

 1 #include <iostream>
 2 #include <string>
 3 
 4 using namespace std;
 5 
 6 class Base
 7 {
 8 public:
 9     Base()
10     {
11         cout << "Base()" << endl;
12         
13         func();
14     }
15     
16     virtual void func() 
17     {
18         cout << "Base::func()" << endl;
19     }
20     
21     virtual ~Base()
22     {
23         func();
24         
25         cout << "~Base()" << endl;
26     }
27 };
28 
29 
30 class Derived : public Base
31 {
32 public:
33     Derived()
34     {
35         cout << "Derived()" << endl;
36         
37         func();
38     }
39     
40     virtual void func()
41     {
42         cout << "Derived::func()" << endl;
43     }
44     
45     ~Derived()
46     {
47         func();
48         
49         cout << "~Derived()" << endl;
50     }
51 };
52 
53 
54 int main()
55 {
56     Base* p = new Derived();
57     
58     // ...
59     
60     delete p;
61     
62     return 0;
63 }

结果如下:

 

由结果可以看出,13、23行的func函数都是调用的当前类中的版本。子类中的调用类似。

 

关于继承中的强制类型转换:

继承中如何正确的使用强制类型转换?

 

示例:

第29行的使用是错误的。

因为编译器会检查dynamic_cast的使用是否合适。29行的使用是不合适的。

因为dynamic_cast要求相关的类中必须有虚函数。

我们无需另外定义一个虚函数,只需把析构函数声明为虚函数即可。

再次编译就可以通过了。

 

示例程序:

 

 可以看到转换不成功时返回0。

dynamic_cast就是为C++中的面向对象程序设计而诞生的。

 

小结:

 

转载于:https://www.cnblogs.com/wanmeishenghuo/p/9588646.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值