如何定义一个只能在栈或者堆上生成的类

来源:互联网 发布:linux怎么显示中文 编辑:程序博客网 时间:2024/06/05 00:38

如何定义一个只能在栈上或者堆上生成的类呢?
这主要考察的是对C++语法和内存管理的掌握,在C++中的内存是如何管理的呢?下面是我自己理解的一张内存管理的图:
内存管理

一.定义一个只能在堆上生成的类
分析:我们都知道一个对象是既可以在栈上生成也可以在堆上new出来,要想生成一个只能在堆上生成的类,也就是说,局部对象,静态对象,全局对象都不能生成,那么我们可以将构造函数写成私有或者保护(类外不可以直接访问的),通过new来构造出一个堆上的对象;
可以在类内new一个对象并提供一个公有的接口来返回这个对象。接下来如果在类外定义类对象的话,只需要调用这个函数即可。貌似这样做还是行不通,因为在类外只能由类对象调用类成员函数,C++是十分强大的,它提供了静态成员函数,所谓的静态成员函数它是没有隐含this指针参数,所以可以使用类型::作用域访问符直接调用静态成员函数,这样问题就解决啦!!!
实现代码如下:

class Base{protected:  //私有或者保护构造函数    Base(int d=0)        :_d(d)    {        cout<<"Base()"<<endl;    }    ~Base()    {        cout<<"~Base()"<<endl;    }public:    //提供静态的成员方法获得当前对象    static Base *GetOBJ(const int& d)    {        cout<<"GetOBJ()"<<endl;        return new Base(d);    }    static void Delete(Base *b)  //可以声明为静态的也可以声明为非静态的    {        cout<<"Delete()"<<endl;        delete b;    }private:    int _d;};void Test()  {      //Base tmp;  //error    Base *b=Base::GetOBJ(5);    Base::Delete(b);}  

私有构造函数
二.定义一个只能在栈上生成的类
想法一:要想只在栈上定义对象,就不能使用new,也不能定义全局和静态变量,我们可以通过以下的方式实现:将构造函数设为私有或者保护,然后写一个公有方法去获取对象,但是不能使用new这个操作符。
代码如下:

class Base{public:    static Base GetObject(int b)  //此处不能返回引用    {        return Base(b);    }    int GetData()    {        return _b;     }private:    Base(int b=0)        :_b(b)    {}private:    int _b;};void Test(){    //Base *tmp=new Base();  //error    Base b = Base::GetObject(5);    cout<<b.GetData()<<endl;}

但是这种想法存在一个弊端就是:依然无法摆脱定义定义静态变量和全局变量。。。
想法二:只能在栈上开辟对象,也就是说不能在堆上开辟了。产生堆对象的唯一方法就是使用new,而禁止使用new也就是不能在堆上产生对象了。由于new执行时会调用operator new, 而operator new是可重载的, 所以将operator new和operator delete重载为私有即可。
实现代码如下:

class Base{public:    Base(int b=0)        :_b(b)    {}    ~Base()    {        cout<<"~Base()"<<endl;    }private:    void *operator new(size_t size);  //对new和delete进行私有处理    void operator delete(void *ptr);private:    int _b;};void Test(){    Base b(10);    //Base *tmp=new Base();  //error虽然此时构造函数是共有的,但是new这个操作符却是私有的}

在这里就分享结束了~~~

阅读全文
0 0
原创粉丝点击