ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

C++ 让类对象只在 堆 或 栈 上创建

2022-05-09 16:00:08  阅读:159  来源: 互联网

标签:函数 对象 创建 创建对象 C++ 编译器 new 构造函数


在C++中,为了让某个类只能通过new来创建(即如果直接创建对象,编译器将报错),应该(B)
A 将构造函数设为私有
B 将析构函数设为私有
C 将构造函数和析构函数均设为私有
D 没有办法能做到

在C++中,类的创建分为两种。一种是静态创建,即直接创建对象;另一种是动态创建对象,即通过 new 创建,如 T *t = new T。要想正确回答上题,就必须知道这两种创建方式的区别。

1. 静态创建

由编译器在栈中为对象分配内存,通过移动栈顶指针获得合适大小的空间,然后调用对象的构造函数生成对象。

2. 动态创建

通过new在堆中创建对象。这个过程分为两步:首先在堆中找到合适大小的空间并分配,然后调用对象的构造函数生成对象。

因为两者都需要调用对象的构造函数,所以通过将构造函数私有化的做法是行不通的。那么还有其他办法吗?这是就需要了解静态创建的另一个特点了。

编译器在为类对象分配栈空间时,会先检查类的析构函数的访问性,其实不光是析构函数,只要是非静态的函数,编译器都会进行检查。如果类的析构函数是私有的,则编译器不会在栈空间上为类对象分配内存。
所以我们只需要将析构函数私有化就可以组织直接创建对象了。由于栈的创建和释放都需要由系统完成的,所以若是无法调用构造或者析构函数,自然会报错。

只能做堆上创建对象

当然为了我们能够正确释放动态创建的对象,我们必须提供一个公有函数,该函数的唯一功能就是删除对象本身。

#include<iostream>
#include<string>

using namespace std;

class Base
{
public:
    Base()
    {
        cout<<"Base()"<<endl;
    }
    void close()
    {
        delete this;
    }
private:
    ~Base()
    {
        cout<<"~Base()"<<endl;
    }
};
int main()
{
    Base *a = new Base();
    a->close();
    return 0;
}

只能在栈上创建对象

既然可以做到只在堆上创建对象,同样的我们可以只在栈上创建对象。
其实理解了这个理念,不难想到我们只需要 让new操作符无法使用即可,要做到这件事,我们可以将 new操作符重载并设置为私有访问即可。是不是很巧妙的方法~
重载new的同时最好重载delete

#include<iostream>
using namespace std;
class Base
{
private:
    void* operator new(size_t t){}
    void operator delete(void* ptr){}
public:
    ~Base()
    {
        cout << "Base destroy" << endl;
    }
};
int main()
{
    //test *A = new test; 错误
    Base A;
}

标签:函数,对象,创建,创建对象,C++,编译器,new,构造函数
来源: https://www.cnblogs.com/codebai/p/16249521.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有