我有一个 C++ 类,我只希望它在堆栈上实例化。我正在使用 API 来访问用另一种(解释型)语言开发的内容,该语言带有自己的垃圾收集功能。这种语言中的机制足够了解,可以将它找到的引用单独保留在堆栈上的任何内容,并且由于该本机类包含这样的引用,因此对于正确的行为,本机 C++ 类的用户所做的操作至关重要永远不要尝试在其他地方分配它的实例。
请注意,我不仅想禁止为我的类的实例分配 new (如果这是我需要做的全部,我可以重载该类的实例)new
运算符并将其设为私有,或从 C++11 起显式删除它),但也不允许该类的任何静态或可能的全局实例。安全地实例化此类的唯一有效方法应该是在堆栈上,我想以某种方式保证这一点。据我所知,制作new
private 或删除它也不会阻止另一个类与我的类一起声明为成员变量以及在堆上分配的实例。
我现在的管理方式是将“Local”一词作为类名称的一部分,以友好地提醒用户该实例仅用于堆栈,但当然,这不是“实际上不是由编译器或任何其他机制强制执行的,我更喜欢一个更具可执行性的解决方案。
理想情况下,我想在编译时确保这一点,如果使用不正确,则编译失败。如果这根本不可能,那么在构造实例时在运行时抛出异常仍然是可接受的后备方案。在 C++11 或 C++14 中工作的解决方案都很好。
请注意,这个问题肯定是NOT与this https://stackoverflow.com/questions/124856/how-do-i-prevent-a-class-from-being-allocated-via-the-new-operator-id-like其一,只想防止分配new
免责声明:据我所知,“堆栈”不是 C++ 标准的一部分,我们有 ASDV(自动存储持续时间变量)。 ABI 可能会定义堆栈。请注意,有时这些会在寄存器中传递,我相信这在您的情况下是可以的。
定义一个CPS(连续传递风格)工厂方法:
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 和 A 的 ctor 参数的 lambda。
return A::cps_make([&](A a) {
/* do something with a */
return true;
});
函数参数始终是内部的 ASDV。
代码如何工作:cps_make 采用一个函子(通常是 lambda),该函子采用给定类型的实例;和可选的 ctor 参数。它创建实例(通过将任何可选参数转发给构造函数),调用函子并返回函子返回的内容。由于仿函数可以是 C++11 中的 lambda,因此它不会破坏正常的代码流程。
CPS 的美妙之处在于,您只需在 C++14 中使用 auto-lambda 即可拥有静态多态性:您的 cps_make() 可以创建您想要的任何内容(层次结构、变体、任意等)。然后,您可以节省封闭层次结构的虚拟开销。您甚至可以为正常流程设置一个 lambda,在 ctor 失败时设置一个 lambda;当例外情况不可行时,这会很方便。
缺点是,目前您无法在 lambda 内部直接使用外部作用域的控制流语句。 /* 提示:我们正在努力。 */
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)