开发者

C++, preventing class instance from being created on the stack (during compiltaion)

I know there are methods to prevent a class from being created on the heap, by preventing the user from using the new and delete operator. I am trying to do just the opposite. I have a class that I want to prevent the user from creating an instance of it on the stack, and that only instances instigated using the new operator will compile. More specifically, I want the following code to receive an error during compilation:

MyClass c1; //compilation error

MyClass* c1 = new MyClass(); //compiles okay

From searching the web, I found this suggestion on how to do it:

class MyClass {
public:
    MyClass();
private:
    void destroy() const { delete this; }

...

private:
    ~MyClass();
};

int main(int argc,char** argv)
{
    MyClass myclass; // <--- error, private destructor called here !!!

    MyClass* myclass_ptr = new MyClass;
    myclass_ptr->destroy();
}

What I don't understand is why this should work. Why would the de开发者_如何学编程structor be called while creating an instance of MyClass?


When myclass reaches the end of its scope (the next }) the compiler calls the destructor to free it from the stack. If the destructor is private, however, then the destructor cannot be accessed, so the class cannot be placed on the stack.

I don't like the look of delete this. In general I think objects should not destroy themselves. Perhaps a better way is to have a private constructor for your class then use a static function to create an instance.

// In class declaration...
static MyClass* Create()
{
    return new MyClass(); // can access private constructor
}

// ...

MyClass myclass; // illegal, cannot access private constructor

MyClass* pMyClass = MyClass::Create();
delete pMyClass; // after usage


Why would the destructor be called while creating an instance of MyClass?

It isn't. It must be invoked automatically when the instance goes out of scope, though. If it's private, the compiler must not generate that code, hence the error.

If you think making the destructor private is obscure, another way to restrict a class to dynamic allocation is to make all the constructors private and only have MyClass::create() functions returning dynamically allocated objects:

class MyClass {
public:
  static MyClass* create()             {return new MyClass();}
  static MyClass* create(const Foo& f) {return new MyClass(f);}
private:
  MyClass();
  MyClass(const Foo&);
};

Note that returning naked pointers to objects that must be deleted is frowned upon. You should return smart pointers instead:

class MyClass {
public:
  static std::shared_ptr<MyClass> create()             {return new MyClass();}
  static std::shared_ptr<MyClass> create(const Foo& f) {return new MyClass(f);}
  // ...
};


Because when instance goes out of scope, it has to be destructed using destructor. Pointer to instance does not do this.


Whenever a local variable goes out of scope, it is destroyed. And on destruction, destructor of object is called. Here, scope is of main function. When program exits, myclass object's destructor will be called


It isn't. The compiler is trying to call the destructor when it goes out of scope, and is indicating to the line of code that produces this effect, which is much more useful than pointing at the end of the function.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜