我有一个 C++ 类,我只希望它在堆栈上被实例化。我正在使用 api 访问以另一种(解释)语言开发的内容,该语言带有自己的垃圾收集。该语言中的机制足以将它找到的任何引用的内容单独留在堆栈上,并且由于该本地类包含这样的引用,因此对于正确的行为至关重要的是,它所执行的本地 C++ 类的用户永远不要尝试在其他任何地方分配它的实例。
注意,我不仅想禁止我的类的实例被分配新的(如果这就是我需要做的,我可以重载类的 new
运算符并将其设为私有(private),或自 C++11 起显式删除它),但也不允许该类的任何静态或可能的全局实例。安全地实例化这个类的唯一有效方法应该是在堆栈上,我想以某种方式保证这一点。据我所知,将 new
设为私有(private)或删除它也不会阻止另一个类被声明为我的类作为成员变量,并且该类的实例被分配在堆上。
我现在的管理方式是将“本地”一词作为类名称的一部分,作为对用户的友好提醒,该实例仅用于堆栈,但当然,这实际上不是由编译器或任何其他机制强制执行的,我更喜欢更具可执行性的解决方案。
理想情况下,我想在编译时确保这一点,如果使用不正确,编译会失败。如果这根本不可能,那么在构造实例时在运行时抛出异常仍然是可接受的回退。在 C++11 或 C++14 中工作的解决方案很好。
请注意,这个问题绝对不与this 相同。一个,它只想用 new
最佳答案
免责声明:据我所知,“堆栈”不是 c++ 标准的一部分,我们有 ASDV(自动存储持续时间变量)。 ABI 可能会定义堆栈。请注意,有时这些是在寄存器中传递的,我认为在您的情况下是可以的。
定义一个CPS(continuation-passing style)工厂方法:
class A {
public:
template<typename F, typename... Args>
static auto cps_make(F f, Args&&... args) {
return f(A(std::forward<Args>(args)...));
}
private:
A(/* ... */) {}
A(const A&) = delete;
A(A&&) = delete;
};
用法:传递一个带 A 的 lambda 和 A 的 ctor 参数。例如
return A::cps_make([&](A a) {
/* do something with a */
return true;
});
函数参数始终是内部的 ASDV。
代码是如何工作的:cps_make 接受一个仿函数(通常是一个 lambda),它接受一个给定类型的实例;和可选的ctor参数。它创建实例(通过将任何可选参数转发给 ctor),调用仿函数并返回仿函数返回的内容。由于仿函数可以是 C++11 中的 lambda,因此不会破坏正常的代码流。
CPS 的美妙之处在于,您只需在 C++14 中使用自动 lambda 即可拥有静态多态性:您的 cps_make() 可以创建几乎任何您想要的东西(层次结构、变体、任何等等)。然后为封闭的层次结构节省虚拟开销。你甚至可以有一个用于正常流程的 lambda,如果 ctor 会失败,则可以有一个;当异常不可行时,这很方便。
缺点是,目前你不能在 lambda 中直接使用外部作用域的控制流语句。/* 提示:我们正在努力。 */
关于c++ - 有没有办法强制实例只在堆栈上?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43506853/