当前位置:  开发笔记 > 编程语言 > 正文

是否可以防止对象的堆栈分配,并且只允许使用"new"实例化它?

如何解决《是否可以防止对象的堆栈分配,并且只允许使用"new"实例化它?》经验,为你挑选了4个好方法。

是否有可能阻止对象的堆栈分配,并且只允许在堆上使用"new"进行隔离?



1> Daemin..:

一种方法是将构造函数设置为私有,并且只允许通过返回指针的静态方法进行构造.例如:

class Foo
{
public:
    ~Foo();
    static Foo* createFoo()
    {
        return new Foo();
    }
private:
    Foo();
    Foo(const Foo&);
    Foo& operator=(const Foo&);
};


或者更好的是一个返回std :: unique_ptr 的静态函数.
+1用于记住使其不可复制.

2> NebulaFox..:

在C++ 11的情况下

class Foo
{
  public:
    ~Foo();
    static Foo* createFoo()
    {
        return new Foo();
    }

    Foo(const Foo &) = delete; // if needed, put as private
    Foo & operator=(const Foo &) = delete; // if needed, put as private
    Foo(Foo &&) = delete; // if needed, put as private
    Foo & operator=(Foo &&) = delete; // if needed, put as private

  private:
    Foo();
};


正如Scott Meyers在"第11项中所述:将已删除的函数更喜欢私有未定义的函数".他的书"Effective Modern C++",最好声明删除的成员函数`public`.--QUOTE--"按照惯例,删除的函数被声明为`public`,而不是`private`.这是有原因的.当客户端代码尝试使用成员函数时,C++会在删除状态之前检查可访问性.当客户端代码时尝试使用删除的`private`函数,一些编译器只抱怨函数是`private`,即使函数的可访问性并不真正影响它是否可以使用."
--QUOTE--"在修改遗留代码以将'私有'和未定义的成员函数替换为已删除的成员函数时,请记住这一点,因为使新函数"公开"通常会产生更好的错误消息."

3> Jason Cohen..:

您可以创建构造函数private,然后提供public静态工厂方法来创建对象.



4> spiderlama..:

以下允许公共构造函数,并通过在运行时抛出来停止堆栈分配.注意thread_local是C++ 11关键字.

class NoStackBase {
    static thread_local bool _heap;
protected:
    NoStackBase() {
        bool _stack = _heap;
        _heap = false;
        if (_stack)
            throw std::logic_error("heap allocations only");
    }
public:
    void* operator new(size_t size) throw (std::bad_alloc) { 
        _heap = true;
        return ::operator new(size);
    }
    void* operator new(size_t size, const std::nothrow_t& nothrow_value) throw () {
        _heap = true;
        return ::operator new(size, nothrow_value);
    }
    void* operator new(size_t size, void* ptr) throw () {
        _heap = true;
        return ::operator new(size, ptr);
    }
    void* operator new[](size_t size) throw (std::bad_alloc) {
        _heap = true;
        return ::operator new[](size);
    }
    void* operator new[](size_t size, const std::nothrow_t& nothrow_value) throw () {
        _heap = true;
        return ::operator new[](size, nothrow_value);
    }
    void* operator new[](size_t size, void* ptr) throw () {
        _heap = true;
        return ::operator new[](size, ptr);
    }
};

bool thread_local NoStackBase::_heap = false;

推荐阅读
牛尾巴2010
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有