【问题标题】:Determine if an object is dynamically allocated or not in C++确定对象是否在 C++ 中动态分配
【发布时间】:2013-07-30 22:47:14
【问题描述】:

我有一个简单的 C++ 类,我需要知道一个对象是否应该在我的程序中的某个点被删除。该机制应该可以跨平台和现代 C++ 编译器移植。

我能想到的一种方法是:有一个成员字段,它不是由构造函数初始化,而是由重载的运算符 new 分配,如下所示:

class message
{
protected:
    int id;
    bool dynamic;
public:
    message(int _id): id(_id)
    {
        // don't touch `dynamic` in the constructor
    }

    void* operator new(size_t size)
    {
        message* m = (message*)::operator new(size);
        m->dynamic = true;
        return m;
    }

    void operator delete(void* m)
    {
        if (((message*)m)->dynamic)
            ::operator delete(m);
    }
};

除了它“感觉”不对的形式,这种方法有什么问题?

编辑: 应该提到该对象是动态的或静态的(并且永远不会是堆栈本地的),因此可以保证将其归零或使用 new 进行初始化。

【问题讨论】:

  • 为什么你需要这个?我可以保证这是错误的方法,即使有一种方法可以按照您的要求进行(我很确定没有)。您不必在运行时决定是否使用 delete 指针,因为您应该知道(编辑:在设计时,即就程序而言,先验)谁拥有什么以及它的生命周期是什么.
  • 制作析构函数private。那么答案总是“是”。
  • @delnan:不,你不能保证 :) 这是一个优化问题。我有一个消息队列,有很多消息经过;在某些情况下它们是动态分配的,但在另一些情况下,只是为了优化,我可以重用静态对象(当然要确保静态对象只进入消息队列一次)。
  • @mojuba:所以你的问题应该是“我有一个消息队列,想像这样优化它,我该如何......”。请参阅XY problem
  • @GManNickG:不,我的问题是:我有可能是静态或动态的对象,我希望这些对象只在一个地方被销毁。

标签: c++ operator-overloading new-operator


【解决方案1】:

构造函数需要将dynamic设置为false,然后你需要一个静态方法,而不是覆盖new

static message *createMessage(int _id)
{
    message *ret = new message(_id);
    ret->dynamic = true;
    return ret;
}

然后调用该方法而不是 newing message

【讨论】:

  • 但是它总是被覆盖,不是吗?
  • 仅当new 被调用时。如果是堆栈分配,dynamic 将保持设置为false
  • @JimBuck: 不,构造函数在 之后 operator new 运行,所以即使operator newdynamic 设置为true,构造函数也会将其替换为@ 987654333@.
  • 确实,我已经编辑了我的问题:在我的例子中,对象要么是动态的,要么是静态的,即要么使用new 创建,要么将所有字段归零。
  • 啊,我编辑没看到你的变化。如果是这样,那么你很好。然而,就像所有其他人提到的那样,这是一个非常糟糕的设计(tm)。
【解决方案2】:

不要这样做。除了它不能工作之外,一个对象不应该管理任何关于它自己生命周期的东西。您可以将unique_ptrshared_ptr 与自定义删除器一起使用,如果对象是堆栈分配的,您可以在其分配站点上知道;在这种情况下,您可以提供一个无操作删除器,如下所示:

struct null_deleter {
  template<class T>
  void operator()(const T*) const {}
};

【讨论】:

  • 您可能没有得到问题。在我的情况下,消息对象在我的程序的一个点被处理并且可能也被销毁,而它们可以在许多不同的地方创建。我想通过尽可能重用静态消息对象来优化我的消息队列,即当一条消息保证只进入队列一次时。这是一个优化问题。所以不,这是运行时而不是编译时的事情。
  • @mojuba:如果他不明白,那是因为你没有说出问题的内容。
猜你喜欢
  • 2013-04-01
  • 2014-12-21
  • 1970-01-01
  • 2012-08-25
  • 2014-12-19
  • 1970-01-01
  • 2014-05-15
  • 1970-01-01
  • 2020-03-12
相关资源
最近更新 更多