【问题标题】:Prevent stack allocation for a class AND for derived classes防止为类和派生类分配堆栈
【发布时间】:2015-11-04 04:59:42
【问题描述】:

有没有办法设计一个类,它及其后代都不能自动分配(在堆栈上),而只能动态分配(在堆中)?

我有一个由场景树表示的 3D 场景,每个对象都有一个父对象和多个子对象。所有场景对象都继承自某个基类SceneObject。我想让它不可能在堆栈上分配这样的对象。

我知道为一个类实现这一点的唯一方法是声明一个受保护的构造函数并提供一个工厂(参见Is it possible to prevent stack allocation of an object and only allow it to be instantiated with 'new'?)。这确实像我想要的那样适用于班级,但不适用于它的后代。派生类的作者需要将构造函数显式声明为非公共的,而我无法控制它,从而提供了出错的可能性。

有没有可能实现我想要的?有什么妥协吗?

【问题讨论】:

  • 妥协:不要把一个类设计得太糟糕以至于不能在堆栈上实例化。这表明你做的很糟糕。
  • @Puppy 我同意。事实上,这个类已经设计好了,我能做的就是创建某种包装器,对现有代码的干扰最小。
  • @EdHeal 我认为这是一个可能的妥协。为了使这项工作如我所愿,我们需要从客户端代码中完全隐藏派生类型,并使它们仅可用于工厂代码。但是,这将不允许将模板函数用作工厂,并要求工厂查看所有类型。它非常适合 C 接口,但我认为不是 C++ 代码的好解决方案。
  • 一个接口模式以及解耦
  • @EdHeal 如果我理解你的想法(而且我不完全确定我是否理解),它将需要对现有架构进行重大更改,这是我们无法承受的。

标签: c++ dynamic-memory-allocation


【解决方案1】:

不是真的,不。

您也许可以通过明确覆盖 operator new 来解决问题,或者将您链接到的答案与模板混合,否则您会被淹没。

我会冒昧地猜测您的全部问题涉及资源管理;如果是这种情况,请查看rule of three;如果您的类具有用户定义的析构函数、复制构造函数或复制赋值 (operator=(const Something&)),您可能需要全部这三个。

【讨论】:

    【解决方案2】:

    我知道这样做的唯一方法是您的 linked answer 所说的 - 将类的构造函数声明为 private 所以除了类本身之外没有人可以创建它的实例,然后提供一个 public 静态方法来创建堆上的类的一个实例。每个想要实例的人都必须调用静态方法。

    【讨论】:

    • 我应该如何从派生类调用private构造函数?
    • 你没有。您必须设计一个类工厂,其中类为自己注册创建者函数(以便他们可以调用自己的私有构造函数),然后用户必须向工厂询问所需类的实例,然后工厂调用适当的创建者.否则,如果您创建构造函数protected,后代可以在其构造函数中调用它,但是没有什么可以阻止某人使用公共构造函数创建后代,然后在堆栈上创建该类的实例。
    • 同意,但我仍然无法理解如何从具有私有构造函数的类继承?
    • 唯一的方法是派生类被声明为基类的friend。否则,基类构造函数必须是publicprotected
    • 然后“后代可以在他们的构造函数中调用它,但是没有什么可以阻止某人使用公共构造函数创建后代,然后在堆栈上创建该类的实例”。因此,我在私有构造函数中根本看不到任何理由。
    猜你喜欢
    • 2010-11-11
    • 2014-01-09
    • 2012-06-05
    • 1970-01-01
    • 1970-01-01
    • 2015-06-05
    • 2020-03-13
    • 2011-02-18
    • 1970-01-01
    相关资源
    最近更新 更多