【问题标题】:How can I tell if an object is statically or dynamically allocated on the constructor? [duplicate]如何判断对象是在构造函数上静态分配还是动态分配? [复制]
【发布时间】:2009-06-18 18:37:51
【问题描述】:

可能重复:
Detect dynamically allocated object?

我有一个对象,无论它的实例是静态分配还是动态分配,它都需要稍微不同的构造。 该对象应该只有一个默认构造函数。因此,拥有两个构造函数,每种情况一个,并让用户显式选择正确的构造函数是不可能的。

有什么合适的方法可以实现吗?

这就是我目前的做法: 我为该对象重载 new 运算符,分配内存,并将返回的指针用作指向(尚未初始化的)实例的指针,并将对象的特定数据成员设置为某个魔术值。 然后,在consutrctor 中,我检查了成员的值。如果是魔法值,那么对象是 99.9% 动态分配的。

这种方法在发布和调试模式下对我来说都没有失败,但是,这似乎是一个可怕的 hack。

【问题讨论】:

  • 不,你必须接受你的黑客攻击。唯一“正确”的方法是修复您的设计。

标签: c++ constructor memory-management


【解决方案1】:

您应该能够实现您想要的,同时保留一个用户可访问的默认构造函数(将用于静态 和 auto 对象——您似乎忽略了 auto 对象的存在,例如局部变量,所以我想你想同样对待这些情况)。

operator new 和一个单独的构造函数都设为私有,并创建一个仅执行return new TheClass(123); 的公共静态方法(这是“工厂方法”设计模式的一种情况)(假设单独的构造函数采用例如整数, 但当然你可以选择任何类型的参数,因为无论如何都不会使用该参数)。

你知道你说对象应该有一个构造函数,但从用户的角度来看,这正是类的行为,并且用户方面没有“构造函数的显式选择”(他只是不能调用new 明确但必须通过您提供的工厂方法,仅此而已)。

【讨论】:

  • 我不确定我明白了。您的意思是用户必须调用静态函数才能分配新实例而不是使用新实例?如果这就是你的意思,那么为什么要重载 new 呢?无论如何,那是不行的,因为该类需要被继承,并且通过您的方法,每个子类还应该定义它自己的静态函数。 * 正如您所提到的,自动对象被视为静态对象。
  • 创建新的私有会阻止用户调用new Foo(),否则他们可能会这样做。是的,如果 all Foo 生活在动态存储中的对象(包括作为基类或成员)需要特殊处理,那么我的建议需要其他类也这样做 - 但您提出的解决方案不起作用那就更好了!-)
【解决方案2】:

任何构造函数都可以用于静态或动态分配。无论他以何种方式分配对象,您都无法强制对象的用户使用特定的构造函数。

【讨论】:

    【解决方案3】:

    我认为你不能在构造函数中说出来。

    我不知道这是否有帮助,但您可以防止通过将析构函数设为私有来静态创建对象。您还需要有一个公共“删除”方法,该方法对动态分配此类对象的代码执行 delete this —— 他们必须执行 obj->Delete() 而不是 delete obj

    【讨论】:

    • 这在基类中根本不起作用。私有析构函数会阻止子类对象永远存在。可以从其子级调用受保护的基类析构函数,这意味着可以在堆栈上创建子类。除非子类也限制了它的 dtor 可见性。无论哪种方式,基类上的受保护 dtor 都是无用的。
    猜你喜欢
    • 1970-01-01
    • 2013-01-06
    • 1970-01-01
    • 2013-01-02
    • 2013-02-26
    • 1970-01-01
    • 1970-01-01
    • 2013-04-01
    • 1970-01-01
    相关资源
    最近更新 更多