验证子类不重写函数也将变成抽象类:
#include<string> #include<iostream> using namespace std; class drink { public: virtual void dele() = 0; }; class mike :public drink { public: void dele(int a) { cout << "牛奶来咯" << endl; } }; class orange :public drink { public: void dele() { cout << "橙汁来咯" << endl; } }; class coke :public drink { public: void dele() { cout << "可乐来咯" << endl; } }; void test1() { mike d; } int main() { test1(); return 0; }
虚析构和纯虚析构
在使用多态的时候,子类中有成员属性开辟空间到堆区,则父类指针在释放的时候无法调用子类中的析构函数
验证:
#include<string> #include<iostream> using namespace std; //人 class people { public: people()//查看是否调用 { cout << "父类内构造函数调用" << endl; } ~people()//查看是否调用 { cout << "父类内析构函数调用" << endl; } virtual void come() = 0;//纯虚函数 }; //男人 class man :public people { public: man(string _name)//查看是否调用 { cout << "子类内构造函数调用" << endl; this->_name = new string(_name);//对名字进行初始化 } ~man()//查看是否调用 { if (_name != NULL) { cout << "子类内析构函数调用" << endl; delete _name; _name = NULL; } } void come() { cout <<*_name<<"来咯" << endl; } string* _name;//用指针来管理名字 }; void test1() { people* p = new man("张三"); p->come(); delete p; p = NULL; } int main() { test1(); return 0; }
那这个时候就会造成内存泄漏,那怎么去解决呢?
将父类中的析构函数变成虚析构或者纯虚析构
#include<string> #include<iostream> using namespace std; //人 class people { public: people()//查看是否调用 { cout << "父类内构造函数调用" << endl; } virtual ~people()//查看是否调用 { cout << "父类内析构函数调用" << endl; } virtual void come() = 0;//纯虚函数 }; //男人 class man :public people { public: man(string _name)//查看是否调用 { cout << "子类内构造函数调用" << endl; this->_name = new string(_name);//对名字进行初始化 } ~man()//查看是否调用 { if (_name != NULL) { cout << "子类内析构函数调用" << endl; delete _name; _name = NULL; } } void come() { cout <<*_name<<"来咯" << endl; } string* _name;//用指针来管理名字 }; void test1() { people* p = new man("张三"); p->come(); delete p; p = NULL; } int main() { test1(); return 0; }
选择就会走子类的调用,如果是纯虚析构呢?
#include<string> #include<iostream> using namespace std; //人 class people { public: people()//查看是否调用 { cout << "父类内构造函数调用" << endl; } virtual ~people() = 0;//查看是否调用 virtual void come() = 0;//纯虚函数 }; //男人 class man :public people { public: man(string _name)//查看是否调用 { cout << "子类内构造函数调用" << endl; this->_name = new string(_name);//对名字进行初始化 } ~man()//查看是否调用 { if (_name != NULL) { cout << "子类内析构函数调用" << endl; delete _name; _name = NULL; } } void come() { cout <<*_name<<"来咯" << endl; } string* _name;//用指针来管理名字 }; void test1() { people* p = new man("张三"); p->come(); delete p; p = NULL; } int main() { test1(); return 0; }
那这里是为什么呢?可以看到报错内容说纯虚析构是无法解析的外部符号,对比上面的虚析构,发现,纯虚析构没有定义,纯虚函数可以不用定义,那为什么纯虚析构就需要定义了呢?这是因为,析构是所有类在销毁前会走的一个函数,这个时候,内部没有实现,就走不过去,就会产生报错,那解决方法就是,在类外定义析构函数,需要在析构函数名前加上作用域:
#include<string> #include<iostream> using namespace std; //人 class people { public: people()//查看是否调用 { cout << "父类内构造函数调用" << endl; } virtual ~people() = 0;//查看是否调用 virtual void come() = 0;//纯虚函数 }; people::~people() { cout << "父类内析构函数调用" << endl; } //男人 class man :public people { public: man(string _name)//查看是否调用 { cout << "子类内构造函数调用" << endl; this->_name = new string(_name);//对名字进行初始化 } ~man()//查看是否调用 { if (_name != NULL) { cout << "子类内析构函数调用" << endl; delete _name; _name = NULL; } } void come() { cout <<*_name<<"来咯" << endl; } string* _name;//用指针来管理名字 }; void test1() { people* p = new man("张三"); p->come(); delete p; p = NULL; } int main() { test1(); return 0; }
虚析构和纯虚析构的共性
可以解决父类指针释放子类对象
都需要有具体的函数实现
虚析构和纯虚析构的区别
有纯虚析构的类也是抽象类,无法实例化对象
验证:
#include<string> #include<iostream> using namespace std; //人 class people { public: people()//查看是否调用 { cout << "父类内构造函数调用" << endl; } virtual ~people() = 0;//查看是否调用 virtual void come() = 0;//纯虚函数 }; people::~people() { cout << "父类内析构函数调用" << endl; } //男人 class man :public people { public: man(string _name)//查看是否调用 { cout << "子类内构造函数调用" << endl; this->_name = new string(_name);//对名字进行初始化 } ~man()//查看是否调用 { if (_name != NULL) { cout << "子类内析构函数调用" << endl; delete _name; _name = NULL; } } void come() { cout <<*_name<<"来咯" << endl; } string* _name;//用指针来管理名字 }; void test1() { people p; } int main() { test1(); return 0; }
面向对象结束,接下来是什么?
随着石碑倒下,看着眼前的楼梯,我心情沉重,“面向对象结束了,那接下来会是什么?”
…
本章知识点(图片形式)