虚函数
在介绍虚析构函数前,先运行一段代码:
#include<iostream>
#define LOG(x) std::cout << x << std::endl
class Base {
public:
Base() {
LOG("Base Contructed");
}
~Base() {
LOG("Base Decontructed");
}
};
class Driver : public Base {
public:
Driver() {
LOG("Driver Contruected");
}
~Driver() {
LOG("Driver Decontruected");
}
};
int main() {
Base* base = new Base();
delete base;
LOG("-----------------");
Driver* driver = new Driver();
delete driver;
LOG("-----------------");
Base* test = new Driver();
delete test;
}
发现在进行多态对象销毁的时候,并没有执行多态对象的析构函数,这样就可能造成内存泄漏。所以一定要确保基类的析构函数为虚函数。
使用virtual关键词加载Base析构函数前方,就可以使其被调用。
类型转换
这里的类型转换分为c语言风格的和c++风格的。
c语言风格的就就是加上括号进行转换,可读性没那么好。
C++有四种转换:static_cast,reinterpret_cast,dynamic_cast,const_cast。可以使用单词搜索
static_cast:静态抓换,会做一些编译时检查。
reinterpret_cast:把内存解释为别的东西。
const_cast:添加或者移除const。
使用了C++风格的代码不同之处在于编译出的检查比较友好,会给出提示。
在使用static_cast、dynamic_cast的时候会产生不同的结果:
Driver* drive = new Driver();
Base* base = drive;
AnotherClass* test = static_cast<AnotherClass*>(base);
AnotherClass* test = dynamic_cast<AnotherClass*>(base);
if (test == NULL) {
LOG("111");
}
static_cast<AnotherClass*>(base)
将不进行运行时类型检查,直接尝试将Base*
类型的指针base
转换为AnotherClass*
类型。如果Driver
和AnotherClass
之间不存在有效的继承关系,这将导致未定义行为。dynamic_cast<AnotherClass*>(base)
将进行运行时类型检查。如果base
实际指向的对象类型不是AnotherClass
或其派生类,则test2
将被设置为nullptr
。
总结来说,static_cast
和dynamic_cast
的主要区别在于dynamic_cast
提供了运行时类型检查,而static_cast
则没有。因此,在执行可能不安全的向下转换时,推荐使用dynamic_cast
以确保类型转换的安全性。