设计一个类,只能在堆上创建?只能在栈上创建?只能创建一个对象?

设计一个类
只能在堆上创建?
只能在栈上创建?
只能创建一个对象?(单例模式**

C++中创建对象的方法有两种,静态创建和动态创建。

1.静态创建

静态创建是由编译器为对象在栈空间中分配一块内存,通过直接移动栈顶指针,取出需要多大的空间,然后再这块内存上钓调用构造函数形成一个栈对象。直接调用类的构造函数。

2.动态创建

通过new运算符将对象建立在堆空间中。首先,调用operator new()函数,在堆空间中找适合的内存并进行分配;然后,调用构造函数构造对象,初始化这块内存空间。间接调用类的构造函数。

限制对象只能在什么地方建立?

1.只能在堆上创建?

意思是不能静态的创建对象,即不能直接调用类的构造函数。只能动态创建对象,使用new操作符完成。

方法一:将构造函数设为私有。

想到这种办法的原因是,将构造函数设为私有后,无法再类外调用构造函数来创建对象,只能使用new运算符来建立对象。
但是这种方法是不可行的,因为new运算符执行的过程中有两步,调用operator new()函数,在堆空间中找适合的内存并进行分配。然后,调用构造函数构造对象,初始化这块内存空间。C++提供new运算符的重载,其实只允许重载operator new()函数,而operator函数用于分配内存,无法提供构造功能。

方法二:将析构函数声明为私有

将析构函数设置为私有的,就可以保证只能在堆上创建一个新的类对象,这样可以自由的控制对象的生命周期,但是徐亚提供创建和撤销的公共接口。

class B
{
public:
   B() {}
    void Destroy()
    {
        delete this; 
    }
private:
       ~B() {}
};
int main()
{
     B *p = new B;
     p ->Destroy(); // 如果类中没有定义Destroy()函数, 而在这里用"delete            p;"代替"p->Destroy();", 则会报错. 因为"delete p;"会去调用类的析构函数, 而在类域外调用类的private成员函数必然会报错.
    return 0;
}

C++是一个静态绑定的语言,在编译的过程中,所有的非虚函数调用都必须分析完成。即使是虚函数,也要检查可访问性。在栈上生成的对象,编译器会帮我们析构,所以析构函数需要访问,但是在堆上生成的对象,由于析构是由程序员自己决定的,所以不一定需要析构函数。

但是问题又出来了,将析构函数设置为私有,不仅仅会限制栈对象生成外,还回限制继承。如果一个类不作为基类,通常会将其构造函数声明为私有的。

方法三:为了限制栈对象,但不想限制继承,可以将析构函数声明为protected。

class B
{
protected:
  ~B() { }
public:
  void destroy()
  {
   delete this ;//调用保护析构函数
  }
};

但是,用new创建的一个对象,但不使用delete释放,而是用destory释放,不符合用户习惯,所以将构造函数也设置为私有或保护,让类提供一个静态成员函数专门用于生产该类型的堆对象。

即使用静态成员函数创建对象和销毁,将构造函数和析构函数声明为protected。(设计模式中的单例模式就是这么实现的)

class B{
protected:
    B(){}
    ~B(){}
public:
    static B* create(){
        return new A();
    }
    static void destory(B* p){
        delete p;    
        p = NULL;
    }
};

2.只在栈上生成对象?

不能动态创建对象,即不能调用new操作符,可以将opterator new和operator delete设置为私有的。

//设计一个类只能在栈上创建对象, //不能调用new 操作符,重载operator new() 和 operator delete() class B { 
private: 
    void * operator new(size_t size){} 
    void operator delete(void *ptr){}
public: 
    B(){}
    ~B(){}
};

猜你喜欢

转载自blog.csdn.net/ZWE7616175/article/details/81145689
今日推荐