1、如果一个类被继承,同时定义了基类以外的成员对象,且基类析构函数不是virtual修饰的,
那么当基类指针或引用指向派生类对象并析构(例如自动对象在函数作用域结束时;或者通过delete)时,会调用基类的析构函数而导致派生类定义的成员没有被析构,产生内存泄露等问题。虽然把析构函数定义成virtual的可以解决这个问题,但是当其它成员函数都不是virtual函数时,会在基类和派生类引入vtable,实例引入vptr造成运行时的性能损失。

如果确定不需要直接而是只通过派生类对象使用基类,可以把析构函数定义为protected(这样会导致基类和派生类外使用自动对象和delete时的错误,因为访问权限禁止调用析构函数),就不会导致以上问题。

测试代码1.1

#ifndef PROTECTED_TEST_H
#define PROTECTED_TEST_H
#include <iostream> class Base
{
public:
Base(){ data_ = new int(); }
~Base(){ std::cout << "Base class deconstructed." << std::endl; }
private:
int* data_;
}; class Child : public Base
{
public:
Child(){ m_data_ = new double(3.14159); }
~Child(){ std::cout << "Child class deconstructed." << std::endl; }
private:
double* m_data_;
}; #endif // PROTECTED_TEST_H int main(int argc, char *argv[])
{
    Base* base = new Child();
    delete base;
}

2、保证对象只生成在堆上。
从语法上来讲,一个函数被声明为protected或者private,那么这个函数就不能从“外部”直接被调用了。
对于protected的函数,子类的“内部”的其他函数可以调用之。
而对于private的函数,只能被本类“内部”的其他函数说调用。

通常使用的场景如下:
A)如果你不想让外面的用户直接构造一个类(假设这个类的名字为A)的对象,而希望用户只能构造这个类A的子类,那你就可以将类A的构造函数/析构函数声明为protected,而将类A的子类的构造函数/析构函数声明为public。例如:
class A
{ protected: A(){}
  public: ....
};
calss B : public A
{ public: B(){}
  ....
};
A a; // error
B b; // ok

B) 单例模式

http://blog.csdn.net/huzzyy/article/details/2562804

析构函数 声明为protected的更多相关文章

  1. C++将类的构造函数、析构函数声明为private或者protected的用途

    如果将构造函数.析构函数声明为private或者protected,表示不能从类的外部正常调用构造和析构函数了. 这种用法的通常使用的场景如下: 1.如果不想让外面的用户直接构造一个类A的对象,而希望 ...

  2. C++多态性中基类析构函数声明为虚函数

    在用基类指针指向派生类时, 在基类析构函数声明为virtual的时候,delete基类指针,会先调用派生类的析构函数,再调用基类的析构函数. 在基类析构函数没有声明为virtual的时候,delete ...

  3. 读书笔记 effective c++ Item 7 在多态基类中将析构函数声明为虚析构函数

    1. 继承体系中关于对象释放遇到的问题描述 1.1 手动释放 关于时间记录有很多种方法,因此为不同的计时方法创建一个TimeKeeper基类和一些派生类就再合理不过了: class TimeKeepe ...

  4. (C++)浅谈多态基类析构函数声明为虚函数

    主要内容: 1.C++类继承中的构造函数和析构函数 2.C++多态性中的静态绑定和动态绑定 3.C++多态性中析构函数声明为虚函数 1.C++类继承中的构造函数和析构函数 在C++的类继承中, 建立对 ...

  5. 条款7:为多态基类析构函数声明为virtual

    基类指针指向子类对象. 子类对象必须位于堆.因此为了避免泄漏内存资源,当指针不使用时,delete掉每一个对象非常重要.但是如果基类的析构函数不声明为virtual.那么指向子类对象的指针delete ...

  6. 在基类中的析构函数声明为virtual

    #include <iostream> using namespace std; class Father { public: ~Father() { cout << &quo ...

  7. [转]c++ 为什么要将基类的析构函数声明为Virtual?

    http://www.cnblogs.com/alephsoul-alephsoul/archive/2012/10/12/2721410.html

  8. <转载>构造函数声明为Private和Protected

    转载http://www.cnblogs.com/this-543273659/archive/2011/08/02/2125487.html将构造函数,析构函数声明为私有和保护的,那么对象如何创建? ...

  9. C++构造函数/析构函数 设置成private的原因

    C++构造函数/析构函数 设置成private的原因 标签(空格分隔): c/c++ 将构造函数,析构函数声明为私有和保护的,那么对象如何创建? 已经不能从外部调用构造函数了,但是对象必须被构造,应该 ...

随机推荐

  1. Storm常用的类

    BaseRichSpout (消息生产者)BaseBasicBolt (消息处理者)TopologyBuilder (拓扑的构建器)Values (将数据存放到values ,发送到下个组件)Tupl ...

  2. LightGBM 调参方法(具体操作)

     sklearn实战-乳腺癌细胞数据挖掘(博主亲自录制视频) https://study.163.com/course/introduction.htm?courseId=1005269003& ...

  3. JavaSE_坚持读源码_HashMap对象_put_Java1.7

    当你往HashMap里面put时,你其实在干什么? /** * Associates the specified value with the specified key in this map. * ...

  4. rsync 文件同步(差异复制)

    Rsync 是一种快速且极其通用的文件复制工具.以其 Delta 传输算法,通过仅发送源文件和目标中现有文件之间的差异来减少通过网络发送的数据量 Rsync 的几种复制方式:Local,SSH 和 R ...

  5. CrawlSpiders模块的使用

    创建文件模板 scrapy genspider -t crawl tencent tencent.com CrawlSpiders就是为爬取整站孕育而生的,我们以前是分页下一页,然后再yied.这样太 ...

  6. vscode 配置踩坑记

    vscode-easy-less 遇到问题最好的解决方式是看官网文档,切记!!! 在web开发当中,经常会写less然后编译成css,当然在VS Code当中也有这样的插件(EasyLess), 但是 ...

  7. Linux记录-使用python临时搭建web服务器

    python2: python -m SimpleHTTPServer 8888 python3: python -m http.server 8888 wget   ip:8888/文件

  8. 在.NET程序中实现HttpServer功能

    亲爱的下午茶   博客园 首页 新随笔 联系 订阅 管理 随笔-6  文章-0  评论-10  在.NET程序中实现HttpServer功能   最近在实现一个可视化数据解析工具,需要在Wpf程序中实 ...

  9. ruby批量插入数据,bulk_insert-----Gem包使用

    文档 https://github.com/jamis/bulk_insert class Book < ActiveRecord::Base end book_attrs = ... # so ...

  10. Lost connection to MySQL server during query,MySQL设置session,global变量及网络IO与索引

    Navicat导出百万级数据时,报错:2013 - Lost connection to MySQL server during query 网上一番搜索,修改mysql如下几处配置文件即可: sel ...