析构函数 private 、virtual的作用

将析构函数声明为private的作用 用声明创建一个栈对象时,会发生如下操作 1、会移动栈顶指针以“挪出”适当大小的空间 2、在这个空间上直接调用对应的构造函数以形成一个栈对象 3、当函数返回时,会调用其析构函数释放这个对象 4、调整栈顶指针收回那块栈内存。 将析构函数设为private除了会限制栈对象生成外,还有其它影响吗?是的,这还会限制继承。 如果一个类不打算作为基类,通常采用的方案就是将其析构函数声明为 阅读详情

类中“私有”权限的含义就是:私有成员只能在类域内被访问,不能在类域外进行访问。   

    

把析构函数定义为私有的,就阻止了用户在类域外对析构函数的使用。这表现在如下两个方面:   
    
1.  禁止用户对此类型的变量进行定义,即禁止在栈内存空间内创建此类型的对象。要创建对象,只能用   new   在堆上进行。   
    

2.  禁止用户在程序中使用   delete   删除此类型对象。对象的删除只能在类内实现,也就是说只有类的实现者才有可能实现对对象的   delete,用户不能随便删除对象。如果用户想删除对象的话,只能按照类的实现者提供的方法进行。  

《More Effective C++》

条款27: 要求或禁止基于堆的对象
有时你想这样管理某些对象,要让某种类型的对象能够自我销毁,也就是能够“delete this”。很明显这种管理方式需要此类型对象被分配在堆中。而其它一些时候你想获得一种保障:“不在堆中分配对象,从而保证某种类型的类不会发生内存泄漏。”如果你在嵌入式系统上工作,就有可能遇到这种情况,发生在嵌入式系统上的内存泄漏是极其严重的,其堆空间是非常珍贵的。有没有可能编写出代码来要求或禁止在基于堆的对象(heap-based object)呢?通常是可以的,不过这种代码也会把“在堆中”的概念搞得比你脑海中所想的要模糊。

要求基于堆的对象
让我们先从必须在堆中建立对象开始说起。为了执行这种限制,你必须找到一种方法禁止以调用“new”以外的其它手段建立对象。这很容易做到。非堆对象(non-heap object)在定义它的地方被自动构造,在生存时间结束时自动被释放,所以只要禁止使用隐式的构造函数和析构函数,就可以实现这种限制。

把这些调用变得不合法的一种最直接的方法是把构造函数和析构函数声明为private。这样做副作用太大。没有理由让这两个函数都是private。最好让析构函数成为private,让构造函数成为public。处理过程与条款26相似,你可以引进一个专用的伪析构函数,用来访问真正的析构函数。客户端调用伪析构函数释放他们建立的对象。

析构函数virtual与非virtual区别

作为通常的原则,如果一个类定义了虚函数,那么它的析构函数就应当是virtual的。因为定义了虚函数则隐含着:这个类会被继承,并且会通过基类的指针指向子类对象,从而得到多态性。   这个类可能会被继承,并且会通过基类的指针指向子类对象”,因此基类的析构函数是否为虚将决定子类的对象是否被析构

示例代码:

  1. #include <iostream.h>  
  2.   
  3. struct A  
  4. {  
  5.     virtual ~A() {cout<<"~A()\n";}  
  6. };  
  7.   
  8. struct B: public A  
  9. {  
  10.     ~B() {cout<<"~B()\n";}  
  11. };  
  12.   
  13. void main()  
  14. {  
  15.     A* p = new B;  
  16.     delete p;  
  17. }  


如果 A的析构函数不是virtual的,那么此时就不是先调用B的析构函数再调用A的析构函数。 
Output:
~A();  
如果A   的析构函数为virtual,则先~B(),再~A()   
Output:
~B();
~A();
       类如果会被派生的话,析构函数一般都应该定义为virtual的,主要不是防止内存泄露,而是为了正确的析构。如果是个封闭类(即不再被派生),就不要定义为virtual的。虚函数毕竟耗费较大的。

不用virtual 的几种情况:
  1、作为非公有基类。仅作为   private   base   class   使用的  class   不需要使用虚拟析构函数   
  2、不作为接口使用的基类。   
  3.   如果你可以保证这个类不被public继承(private/protected继承的话,在非friend函数/类中就无法用基类指针指向派生类了)   
  4.   如果它的所有派生类(包括派生类的派生类)的析构函数都是trivial的(这里的trivial指的是在程序员的层次什么事也不做)   
  5.   如果不需要用基类的指针指向派生类的对象   
  在这五种情况下,不把析构函数声明为virtual都是可以的,何况效率会高一些——但前提是你得保证前提的成立——不过这些保证常常是很难100%的:谁能保证别人在派生你的类的时候,析构函数是trivial的,或者别人不用你提供的基类的指针指向派生类对象?这些常常是很难得到保证的。  

声明基类的析构函数为virtual并非总是为了防止memory   leak   另外这也只是作为一般的原则(基类中有虚函数则把其析构函数声明为virtual)。如果你的析构函数什么事也不作,从效果上来说,不声明为virtual也无妨

Private Bytes、Working Set、Virtual Size 的区别 进程占用内存、进程申请的内存和进程所依赖的动态库申请的内存总和,不包括进程所依赖的动态库占用的内存、mmap的内存。不一定在物理内存上,可以被交换到磁盘上,所以可以比Working Set大。由于也包括进程依赖动态库所申请的内存,所以不能判断内存泄漏是由进程导致的还是动态库导致的。 阅读详情

相关推荐

ethernet virtual private network介绍

ethernet virtual private network背景         ethernet virtual private network RFC的全程是BGP MPLS-Based Ethernet VPN, 最开始由RFC7432定义,要了解ethernet virtual private networ...

qq_43691045的博客 2608

【C++】private 函数用 virtual 修饰的一个用途

private 函数用 virtual 修饰时,可以用于“不想对外暴露 virtual 函数,而提供一个 public 的非虚函数给外界访问”的情形。具体看如下代码: #include <QCoreApplication> #include <QDebug> class Father { public: void func() { vfunc(); } private: virtual void vfunc() {

江湖人称菠萝包 1872

Wonderware Intouch 2014R2 SP1 安装教程

下载Wonderware System Platform 2014R2 SP1 and Intouch 2014R2 SP1的安装压缩包,如下 软件的下载连接地址如下: https://pan.baidu.com/s/1a2GnI_nfT3vK1l49B94FIQ, 提取码:6ec6 或者直接微信扫描下面的二维码 管理员运行下面的setup.exe可执行程序, 进入安装,选择Product Based Selection, 自定义选择需要安装的程序,如下: 普通的Into

工控先生 3万+

【C++ 析构函数】C++ 私有析构函数的作用

C++ 私有析构函数的作用

探索C++编程的奥秘,分享深入的技术见解和实践,旨在激发读者创造力与解决问题的思维。 2088

RIGOL DS1102E示波器新手必看:从开机到捕获第一个波形的5分钟指南

本文为RIGOL DS1102E示波器新手提供了一份快速上手指南。内容涵盖从开机、探头校准到捕获第一个波形的完整流程,重点解析了触发设置、自动测量等核心操作,并指出了探头衰减比设置等常见误区,帮助用户快速掌握这款经典数字示波器的基本使用方法。

dream的博客 740

Error response from daemon: Get “https://index.docker.io/v1/search?q=nginx&n=25“:

在使用docker seach 命令搜索镜像的时候遇到这个错误,docker pull是可以正常下载镜像的,关于这个问题,本文提供解决方案,完全可行。

猿小白的博客 1万+

c++ private、protect、public、virtual详细说明***

今天遇到有些同事居然对这些关键字的权限等还不是特别了解,容易弄混淆,今天总结下。 private: 私有控制符。这类成员只能被本类中的成员函数和类的友元函数访问。 protected: 受保护控制符。这类成员可以被本类中的成员函数和类的友元函数访问,也可以被派生类的成员函数和派生类的友元函数访问。 public: 共有控制符。这类成员可以被本类中的成员函数和类的友元函数访问,也可...

随意的风的专栏 6997

【深度学习新浪潮】智能体在图像处理领域的技术突破与实践指南

智能体正在重构图像处理的技术版图:从多智能体分工的"专业化协作",到多模态统一的"极简架构",再到工具增强的"实战能力",技术突破不断降低开发门槛并拓展应用边界。对于开发者而言,2025年的核心机遇在于结合具体场景选择成熟框架(如医疗用IteR-MRL、工业用NVIDIA NIM),通过微调与工具集成快速落地解决方案。随着硬件成本下降与开源生态完善,图像处理智能体将从当前的"高端场景赋能"走向"千行百业普及",真正成为数字世界的"视觉感知与操作核心"。

专注:太空算力、AI infra、异构调度、大模型成本工程 439

【面向对象程序设计C++】期末复习

静态成员函数不能被声明为virtual函数、不能被声明为const和volatile。 静态与非静态成员函数之间有一个主要的区别。那就是静态成员函数没有this指针。 虚函数的调用关系:this -> vptr -> vtable ->virtual function 静态成员函数只能访问静态成员变量->静态成员函数没有this指针 静态成员是可以独立访问的,也就是说,无须创建任何对象实例就可以访问。->静态成员函数不属于任何对象,而是属于类的。 #include <io

queue1997的博客 1733

YOLOv8的特征蒸馏代码应用讲解(CWD/MGD/mimic/在线蒸馏/逻辑蒸馏)

基于YOLOv8的逻辑蒸馏、特征蒸馏、在线蒸馏等方法代码介绍。

qq_41920323的博客 2583

元数据治理实战:构建企业数据地图与血缘体系

元数据(Metadata)是描述数据的数据,是你能了解“数据是怎么来的”、“它是做什么的”、“能不能用”的基础信息。📌 举个例子:order_idstringods_order定义:平台内用户在订单系统中产生的唯一订单编号更新时间:每天凌晨 2 点,由 Airflow 调度任务生成所属人:张三(数据开发部)🔍 这些信息本身不直接参与计算,但它们是数据可管理、可追踪、可评估的基础。模块实战建议元数据类型技术 + 业务 + 操作元数据三类统一治理治理路径。

晴天彩虹雨的博客 290

参数进阶:ref out params三剑客

参数进阶:ref out params三剑客 ref out 使用方法基本一样 定义和使用时必须传递关键字。 定义时:out后的参数需要在方法内先进行初始化, out传递的参数不进行初始化为合法 ref传递的参数必须初始化: 所以,ref后的参数当做正常的参数使用即可。 params 关键字支持传递多个参数 示例代码: void Start() { int a = 1; fun_ref(ref a); print(a); int b = 2; fun_out(ou

飞浪纪元FE的博客 176

[RK3568 Android11] 开发之调试RK809 codec音频-SPK喇叭

目录 前言 一、注册声卡顺序 二、SPK喇叭路由配置 三、tinyalsa调试工具 前言 瑞芯微RK809是一种复杂的功率管理集成电路(PMIC)集成编解码器,适用于由外部电源供电的多核系统应用;同时它也集成了音频编解码器,这样在硬件设计上可以直接使用RK809 codec功能,不必再外挂个其他codec芯片;RK809 codec不仅支持SPK,还支持耳机,MIC功能; 一、注册声卡顺序 设备树dts里面原厂帮我们配置好了rk809_sound,我们直接...

~未来可期~ 7413

【一篇即毕业系列】C++的继承&&多继承&&多态&&纯虚函数&&抽象类 --- 从基础到通天!!!

本文介绍了C++中继承与抽象类的核心概念。重点讲解了多态的实现方式:通过虚函数(virtual)和父类指针指向子类对象来实现运行时动态绑定。文章详细说明了三种继承权限(public/protected/private)的区别,并指出实际开发中主要使用public继承。此外,还介绍了纯虚函数(=0)和抽象类(不可实例化)的概念。最后讨论了多继承和虚继承的使用场景,虚继承通过virtual关键字解决了多继承中的二义性和数据冗余问题。文中包含代码示例,帮助理解这些面向对象编程的重要特性。

maybe_Tian_Xia的博客 525

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

C++学习日志——面向对象篇3.8

语句就是上面理解当没有实例化基类直接实例化派生类时派生类对象和基类之间关系的证明)通过在Test函数的输出语句中添加一个输出c的Animal类的m_Data值,证明了实际上基类中的m_Data值并没有因为派生类的重名和构造函数导致被覆盖掉,但是地址又是如何呢?所谓的“多继承”,就是指对于一个派生类,它不仅可以单单继承一个类,还可以同时继承多个基类,即当我们需要实现一个类并且希望它能过完成多个已经实现的类的功能时,继承就像接口一样,此时新的派生类只需要完成调用接口即可,这很好的体现了C++的面向对象特性。

sueie的博客 358

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

C++开发过程笔记~~持续更新~~

个人C++开发笔记,记录相关问题

欢迎进入我的个人博客https://galaxyzh.github.io/ 1056

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

【COMP282 LEC 1-2】

COMP282 LEC1-2

WINNER0215的博客 273

析构函数声明为私有的作用

http://blog.youkuaiyun.com/jia_xiaoxin/article/details/3348045 当我们规定类只能在堆上分配内存时,就可以将析构函数声明为私有的。 class alloc { public:     alloc(): private:    ~alloc(); };   如果在栈上分配空间,类在离开作用域时会调用析构函数释放空间,此时无法调用...

weixin_33743880的博客 95

SSL Virtual Private Network的技术分析

我们先来介绍一下SSL协议。 SSL(安全套接字层):介于传输层和上层应用层协议之间的协议。为两台机器之间提供安全通道的协议。 SSL协议介绍: 1、SSL握手协议 SSL握手协议被封装在SSL记录协议中,该协议允许服务器与客户端在应用程序传输和接收数据之前互相认证、协商加密算法和密钥。在初次建立SSL连接时,服务器与客户机交换一系列消息 2、SSL修改密文协议 ...

嚴 帅的博客 881

析构函数virtual与非virtual区别

析构函数virtual与非virtual区别 作为通常的原则,如果一个类定义了虚函数,那么它的析构函数就应当是virtual的。因为定义了虚函数则隐含着:这个类会被继承,并且会通过基类的指针指向子类对象,从而得到多态性。   这个类可能会被继承,并且会通过基类的指针指向子类对象”,因此基类的析构函数是否为虚将决定子类的对象是否被析构。 很多时候你只能够获取基类指针,但却不知道它

自愚自乐的专栏 622

对private内存、virtual内存的一些讲解

对private内存、virtual内存的一些讲解 Note : This guide is applicable to Linux kernels 2.6.14 and above, which adds support for smaps, per-mapping data, including data on each mapping's rss usage. Most Admins

子木小乔 4863

public protected private & virtual

private: 私有控制符。这类成员只能被本类中的成员函数和类的友元函数访问。 protected: 受保护控制符。这类成员可以被本类中的成员函数和类的友元函数访问,也可以被派生类的成员函数和类的友元函数访问。 public: 共有控制符。这类成员可以被本类中的成员函数和类的友元函数访问,也可以被类作用域内的其他函数引用。 virtual: C++通过虚

小熊不去实验室 1813

创建 virtual private catalog (虚拟用户目录)(oracle 11g)

说明:    一个 catalog  可以注册多个数据库:    而注册多个 target  数据库以后,可以分给不同的用户进行管理,VPC    实验操作如: 1、注册 target 数据库 PROD1 到 catalog [oracle@catalog ~]$ rman catalog catowner/password@catalog_ORCL target sys/1

namesliu 刘林 的专栏 5146
上一篇: c中的字符串函数
下一篇: 赋值操作符和拷贝构造函数
Study_2011
博客等级 码龄15年 4粉丝 14原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值