C++禁止堆栈实例但允许新删除

J. *_*Doe 4 c++ c++11 c++14 c++17

基本上我想要的是:

class MyClass{
    public:
        MyClass() = default;
    // what should I do?
}

MyClass mc; // compile time error;
auto pmc = new MyClass; //OK
delete pmc; //OK too
Run Code Online (Sandbox Code Playgroud)

我知道我可以通过隐藏构造函数(现在不能在类外部新建)或隐藏析构函数(现在不能在类外删除)或隐藏两者来使其成为堆.如果我不想引入一些新的命名函数并且只想要好的旧的和删除怎么办?是否有可能(即使是黑客攻击)?

Dav*_* M. 6

我的"像一个聪明的指针,但不是"的想法:

#include <iostream>

class MyClass_ {
  private:
    /**/     MyClass_( void ) { }
    /**/    ~MyClass_( void ) { }
  public:
    void     func( void ) const { std::cout << "Hello" << std::endl; }

    friend class MyClass;
} ;

class MyClass {
  public:
    /**/     MyClass( void ) : p( new MyClass_ ) { }
    /**/    ~MyClass( void ) { delete p; }

    // Tricky implementation details follow...
    // The question in all cases is, who owns the MyClass_ that has been
    // allocated on the heap?  Do you always allocate a new one, and then
    // copy the guts?  (That might be expensive!)  Do you change ownership?
    // Then what about the other MyClass?  What does it point to?
    // Or do you share ownership?  Then you need to ref-count so you don't
    // delete too soon.  (And this whole thing turns into an ordinary
    // shared_ptr<MyClass_>)

    /**/     MyClass( const MyClass &o ) { }
    /**/     MyClass( MyClass &&o ) { }
    MyClass &operator=( const MyClass &o ) { }
    MyClass &operator=( MyClass &&o ) { }

    MyClass_ * operator->( void ) { return p; }
    const MyClass_ * operator->( void ) const { return p; }

  private:
    MyClass_ *p;
} ;

int
main( int, char ** )
{
    MyClass  a;                  // this will be destroyed properly
    MyClass *b = new MyClass;    // this will leak if you don't delete it

    a->func( );
    (*b)->func( );

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

  • 这非常聪明.它说明了类只能在堆上生存的事实实际上并不是用户需要注意的事情.他们所关心的只是实例化一个对象.通过将堆分配隐藏为实现细节,您还可以根据需要保留包装器对象的值语义. (3认同)