C++不允许堆栈实例,但允许新的删除



基本上我想要的是:

class MyClass{
    public:
        MyClass() = default;
    // what should I do?
}
MyClass mc; // compile time error;
auto pmc = new MyClass; //OK
delete pmc; //OK too

我知道我可以通过隐藏构造函数(现在不能在类外新建)或隐藏析构函数(现在不能在类外删除)或同时隐藏两者来使其仅堆。如果我不想引入一些新的命名函数,而只想使用旧的新函数并删除怎么办?有可能吗(即使有黑客)?

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

#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;
}

这听起来不像你想要的,但把它包围在另一个类中。这样,您就可以强制将存储从堆中分配出来,并使此类详细信息远离 API 用户。

一种常见的方法是让你的构造函数private,并添加一些返回指针的static成员函数(你可以称之为工厂或制造函数)。

所以你的班级看起来像

class MyClass{
    private:
        MyClass() = default;
    public:
        static MyClass* make() { return new MyClass;  };
    // what should I do?
}

您将编写代码:

 auto mc = MyClass::make();

其他地方(而不是new MyClass

等。但是,请注意五法则,并考虑使用(作为MyClass::make的返回类型)<memory>标头中的一些智能指针。

您还可以使用自己的一元operator ->operator *定义自己的智能指针类,以及受std::make_shared启发的自己的可变参数模板...

只想要好的旧的新的并删除

在真正的C++11中,这是不受欢迎的,可能被认为是糟糕的风格。您应该避免在库外部使用显式new,并采用一些智能指针编码方式。

最新更新