C/C++中的虚析构函数和私有析构函数的使用
代码:
#include <iostream> using namespace std; class A{
public:
A(){
cout<<"construct A"<<endl;
}
virtual ~A(){
cout<<"destory A"<<endl;
}
}; class B:public A{
public:
B(){
cout<<"construct B"<<endl;
}
~B(){
cout<<"destory B"<<endl;
}
}; class C{
~C(){
cout<<"destory C"<<endl;
}
public:
C(){
cout<<"construct C"<<endl;
}
void destory(){
delete this;
}
};
int main(){ A* p = new B;
delete p;
C* p1 = new C;//new为在堆上分配空间
cout<<"new分配地址 "<<p1<<endl;
//delete p1; //编译出错,不能直接delete
p1->destory(); //C t; //编译出错,构造函数为私有的 A a;
cout<<"不用new "<<&a<<endl; return ;
}
输出:
construct A
construct B
destory B
destory A
construct C
new分配地址 0x1623c20
destory C
construct A
不用new 0x7ffcb2ad25b0
destory A
分析:
1、虚析构函数的作用:当基类指针指向派生类并delete时,可以调用派生类的析构函数;
2、私有析构函数的作用:令对象只能在堆上生成,即用new方法。原理是C++是一个静态绑定语言,在编译过程中,所有的非虚函数调用都必须分析完成(虚函数也要检查可访问性)。因此,当在栈上生成对象时,对象会自动析构,即析构函数必须可以访问。而在堆上生成对象时,析构步骤由程序员控制,不一定需要析构函数。同时,此生成对象不能直接delete删除,析构过程还需要一个专门的成员函数(代码中的destory()函数)。
虚析构函数与抽象类结合
代码:
#include <iostream>
#include <cstdio> using namespace std; class A{
public:
//virtual ~A()=0; //如果抽象基类析构函数不需要实现,也可以用纯虚析构函数,但必须在类外加以声明
virtual ~A(){
cout<<"destory A"<<endl;
}
virtual void func()=;
};
//A::~A(){} class B:public A{
public:
~B(){
cout<<"destory B"<<endl;
}
//virtual void func()=0; //如果不实现纯虚函数,则必须重新说明,注意抽象类无法实例化
void func(){
cout<<"this is function"<<endl;
}
}; int main(int argc,char* argv[]){ A* pA = new B;
delete pA; return ;
}
输出:
destory B
destory A
C/C++中的虚析构函数和私有析构函数的使用的更多相关文章
- C++箴言:避免构造或析构函数中调用虚函数
如果你已经从另外一种语言如C#或者Java转向了C++,你会觉得,避免在类的构造函数或者析构函数中调用虚函数这一原则有点违背直觉.但是在C++中,违反这个原则会给你带来难以预料的后果和无尽的烦恼. 正 ...
- C++进阶--构造函数和析构函数中的虚函数
//############################################################################ /* 任何时候都不要在构造函数或析构函数中 ...
- EC笔记,第二部分:9.不在构造、析构函数中调用虚函数
9.不在构造.析构函数中调用虚函数 1.在构造函数和析构函数中调用虚函数会产生什么结果呢? #; } 上述程序会产生什么样的输出呢? 你一定会以为会输出: cls2 make cls2 delete ...
- 读书笔记 effective c++ Item 9 绝不要在构造函数或者析构函数中调用虚函数
关于构造函数的一个违反直觉的行为 我会以重复标题开始:你不应该在构造或者析构的过程中调用虚函数,因为这些调用的结果会和你想的不一样.如果你同时是一个java或者c#程序员,那么请着重注意这个条款,因为 ...
- 【校招面试 之 C/C++】第10题 C++不在构造函数和析构函数中调用虚函数
1.不要在构造函数中调用虚函数的原因 在概念上,构造函数的工作是为对象进行初始化.在构造函数完成之前,被构造的对象被认为“未完全生成”.当创建某个派生类的对象时,如果在它的基类的构造函数中调用虚函数, ...
- 在构造函数和析构函数中调用虚函数------新标准c++程序设计
在构造函数和析构函数中调用虚函数不是多态,因为编译时即可确定调用的是哪个函数.如果本类有该函数,调用的就是本类的函数:如果本类没有,调用的就是直接基类的函数:如果基类没有,调用的就是间接基类的函数,以 ...
- C++中的虚析构函数、纯虚析构函数具体解释
C++中析构函数能够为纯虚函数吗? 众所周知.在实现多态的过程中,一般将基类的析构函数设为virtual.以便在delete的时候能够多态的链式调用.那么析构函数能否够设为纯虚呢? class CBa ...
- C++构造与析构函数中调用虚函数的问题
前些天想把以前写的内存池算法重写一遍,跨平台是第一目标,当时突发奇想,因为不愿意做成一大堆#if..#end,所以想利用C++的多态性,但是怎么让内存池完好退出却没想到自认为完美的方案.但是一个很偶然 ...
- C# 构造函数中调用虚方法的问题
请看下面代码: using System; public class A{ public A(){ M1(); } public virtual void M1(){} } public class ...
随机推荐
- shell中的declare命令
declare命令有如下选项: -a 声明一个数组 -i 声明一个整型 -f 打印所有函数定义 -F 仅打印函数名字 -r 声明一个readonly变量,该变量的值无法改变,并且不能为unset -x ...
- C++ 基本数据结构整理
Hash Map (Unordered_map) Insert #include <unordered_map> using namespace std; unordered_map &l ...
- MySQL 聚簇索引
聚簇索引并不是一种单独的索引类型,而是一种数据存储方式.具体的细节依赖于其实现方式,但innoddb 的聚簇索引实际上在同一个结构中保存了B-Tree索引和数据行. 当表有聚簇索引时,它的数据实际上存 ...
- Flask学习记录之Flask-Admin
相信用过Django框架的都不会忘记它强大的Admin功能,Flask-admin是一款能够与Django Admin所媲美的扩展,能够快速创建Web管理界面,实现了用户.文件增删改查等常用功能:也可 ...
- C语言基础学习学习前的准备-1
C语言概述 欢迎来到C的世界!C语言之所以命名为C,是因为C语言源自Ken Thompson发明的B语言.它是一种可移植语言,通常一个C程序可以经过很少的改动甚至不经改动就可以在其它系统上运行:它强大 ...
- GO语言练习ONE
- Lintcode--006(交叉字符串)
Given three strings: s1, s2, s3, determine whether s3 is formed by the interleaving of s1 and s2. Ex ...
- Linux/Unix工具与正则表达式的POSIX规范
http://www.infoq.com/cn/news/2011/07/regular-expressions-6-POSIX 对正则表达式有基本了解的读者,一定不会陌生『\d』.『[a-z]+』之 ...
- HDU5044---Tree 树链剖分
大致题意:add1 u v u到v路径上所有点的权值加上k,add2 u 到v路径上所有边的权值加上k 最后输出所有点的权值,边的权值..树链剖分预处理然后来个线性O(n)的操作.刚开始用线段树 ...
- debuggap,移动端调试新方式
最近发现了一个移动端调试的新技能,这里简单描述一下基本情况. 移动端调试常遇到的问题 手机访问只能看到页面的展现,除此之外看不到任何其他信息 无法像调试PC页面那么方便的查看js.dom.networ ...