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

时间:2017-10-21 04:29:48

标签: 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

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

3 个答案:

答案 0 :(得分: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;
}

答案 1 :(得分:0)

听起来不像你想要的那样,但是把它包围在另一个班级里。这样,您可以强制执行存储,从堆中分配存储,并使这些详细信息远离API用户。

答案 2 :(得分:0)

通常的方法是创建构造函数private,并添加一些static成员函数(可以将其称为工厂或函数),它返回一个指针。

所以你的课程看起来像是

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

你会编码:

 auto mc = MyClass::make();

其他地方(而不是new MyClass

等。但请注意rule of five并考虑使用smart pointer中的某些<memory> header作为MyClass::make的返回类型。

您还可以使用自己的一元operator ->operator *定义自己的智能指针类,并使用variadic templates启发自己的std::make_shared ...

  

只想要旧的新旧并删除

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