C++笔记 | C++ 如何定义一个只能在堆上(栈上)生成对象的类

在C++中,类的对象的建立分为两种,一种是静态建立,比如A a;一种是动态建立,比如A * a=new A();

对于静态建立而言,编译器将栈顶指针的位置分配给a,并且直接调用a的构造函数,将栈顶指针后移,而对于动态建立而言,编译器搜索堆中可用的空间,将它分配给a,然后间接调用a的构造函数来构造a

1.如何将类只能初始化在堆上
  容易想到将构造函数设为私有。在构造函数私有之后,无法在类外部调用构造函数来构造类对象,只能使用new运算符来建立对象。然而,前面已经说过,new运算符的执行过程分为两步,C++提供new运算符的重载,其实是只允许重载operator new()函数,而operator()函数用于分配内存,无法提供构造功能。因此,这种方法不可以。

所以,编译器在为类对象分配栈空间时,会先检查类的析构函数的访问性,其实不光是析构函数,只要是非静态的函数,编译器都会进行检查。如果类的析构函数是私有的,则编译器不会在栈空间上为类对象分配内存。

因此,将析构函数设为私有,类对象就无法建立在栈上了。代码如下

所以,代码如下:

Class A

{

  Public:

  A(){};

   Voiddestroy() {delete this;}

  Private:

  ~A(){};

}

构造函数可以直接调用。类中必须提供一个destory函数,来进行内存空间的释放。类对象使用完成后,必须调用destory函数,因为析构函数是私有的,不能通过delete来释放对象,系统也无法自动释放对象。

  上述方法的一个缺点就是,无法解决继承问题。如果A作为其它类的基类,则析构函数通常要设为virtual,然后在子类重写,以实现多态

  因此可以将析构函数设置为protected类型以实现需要的功能

 

但是使用New声明使用destroy释放有点奇怪,因此使用creat函数声明

Class A

{

  Public:

   StaticA* creat()

{

     Return new A();

}

   Voiddestroy() {delete this;}

  protected:

  ~A(){};

A(){};

}

这样就实现了类只能在堆中初始化而不能在栈中初始化

2.如何将类只能初始化在栈上

首先类假如需要初始化在堆上,其需要new运算符,我们可以重载new运算符,将其设为私有或者是保护类型,来使得类只能初始化在栈上,

这里需要说一下C++的new运算符,C++的new运算符有三种,1一种是我们平时常用的那一种,new operator,它的功能是调用后两种new来进行类的初始化,2第二种是operator new,只有这一种可以重载重载它的时候参数为size_t  3第三种为placement new,这一种用来初始化对象,用来调用构造函数

Class A

{

  private:

   void* operator(size_t t)

{}

Void operator delete (void * ptr)

{}

Public:

  ~A(){};

A(){};

}

这里面的delete的重载可以加上去,也可以不加上去

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值