美文网首页C++ 杂记
C++ 如何保证一个对象只能在堆上生成?

C++ 如何保证一个对象只能在堆上生成?

作者: 赵者也 | 来源:发表于2020-06-19 22:40 被阅读0次

因为 C++ 是静态绑定语言。在编译过程中,所有的非虚函数调用都必须被解析完成。即使是虚函数,也需检查可访问性。

当在栈上生成对象时,对象会自动析构,此时对析构函数的需求是必须的,因此析构函数必须是可以访问。而堆上生成的对象,由于其具体的析构时机由开发者来控制,此时对析构函数的需求不是必须的。

上面是保证了不能在栈上生成对象的原理,接下来我们需要证明我们确实只能在堆上生成它。下面是一个测试的示例(使用了 Qt Creator IDE 及部分 Qt 类):

#include <QCoreApplication>
#include <QDebug>

namespace {
const QString OUTPUT_INFO_SATRT("CreatNewOnly===debug output:");
}

class CreatNewOnly
{
    ~CreatNewOnly() {
        qDebug() << OUTPUT_INFO_SATRT << "~CreatNewOnly() called";
    }
public:
    CreatNewOnly() {
        qDebug() << OUTPUT_INFO_SATRT << "CreatNewOnly() called";
    }

    void destroy() {
        delete this;
        qDebug() << OUTPUT_INFO_SATRT << "destroy() called";
    }
};

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

//    CreatNewOnly test001;
    CreatNewOnly* test002 = new CreatNewOnly;
//    delete test002;
    test002->destroy();
    test002 = nullptr;

    return a.exec();
}

其输出如下图所示:

2020-04-26 13-51-04屏幕截图.png

这里 CreatNewOnly 与一般对象唯一的区别是它的析构函数是私有的。

我们知道 delete 操作会调用析构函数,但是因为 CreatNewOnly 的析构函数是私有的,所以直接通过 delete 操作指针对象是不能通过编译的。那么我们该如何释放 new 出来的对象呢?我们可以像示例代码一样提供一个公有的成员函数,用于完成 delete 操作。在成员函数中,私有的析构函数是可以访问的。此时的 detele 操作也是可以编译通过的。

下面是注释掉的代码显示的编译问题:

创建栈对象的错误提示信息 delete 操作的错误提示信息

使用场景举例:

  1. 禁止用户在栈内存空间内创建此类型的对象。要创建对象,只能用 new 在堆上进行。
  2. 我们设计的类需要在析构时必须要执行一些操作,但是又担心类的使用者不会主动去执行这些操作时。

相关文章

  • C++ 如何保证一个对象只能在堆上生成?

    因为 C++ 是静态绑定语言。在编译过程中,所有的非虚函数调用都必须被解析完成。即使是虚函数,也需检查可访问性。 ...

  • C# 静态调用C++ 生成的dll,即非托管dll

    C++文集板块有一节《C++ 如何生成一个DLL动态链接库》已经讲述了,C++如何生成一个动态链接库CPPDLLD...

  • Java对象内存布局之谜

    Java对象内存布局之谜 一个Java对象在堆上除了成员信息,还有其他内容吗?他在堆上是如何布局的?接下来本文将以...

  • Java GC 了解

    GC 是什么和为什么? 我们知道,java代码在执行过程中,会在堆上生成一个个的对象,即使该线程的代码执行结束,只...

  • golang逃逸(escape)的问题

    在C语言中,使用malloc函数分配生成的变量都在堆上面,其他的普通变量都在栈上面。使用C++语言,使用new生成...

  • Singleton pattern-单例模式

    解决问题 保证只生成一个对象的实例 应用场景 仅需要一个对象的场景:比如打印机打印(无论多少任务,一次只打印一个)...

  • Singleton(单态设计模式)之全局随机数生成器的设计

    随机数生成器的设计要点 唯一性(保证全局只由一个类对象来生成) 什么是单态设计模式? 单态设计模式就是:一个类只生...

  • java序列化,深度解析

    对象序列化是什么? java程序启动会启动一个相应的jvm进程,在程序运行期间,若新生成了对象,则会在jvm堆上分...

  • 深入学习java笔记-2.垃圾回收机制

    1.C++对比Java C++ 自己生成对象自己回收。(食堂)Java 生成的对象会有专门的GC回收。(饭店) 2...

  • Go性能优化1期

    1 内存优化 1.1 小对象合并成结构体一次分配,减少内存分配次数 做过C/C++的同学可能知道,小对象在堆上频繁...

网友评论

    本文标题:C++ 如何保证一个对象只能在堆上生成?

    本文链接:https://www.haomeiwen.com/subject/mjsdwhtx.html