0

考虑这个代码片段:

#include <iostream>

using namespace std;

class X {
  public:
    class Z {
      public:
        void f() {
          cout << "Z().f()" << endl;
        }
    };

    class Y {
      public:
        int A;
        Y(int x) {
          A = x;
        }

        int c() {
          return A;
        }
    };

    public:
      Z* z;

      // How to free Y instance ?
      Y* a(int x) {
        Y* y = new Y(x);
        return y;
      }

    public:
      X() {
        z = new Z();
      }

      ~X() {
        delete z;
      }
};

int main(void) {
  int a;
  X* x = new X();
  cout << "input :" << endl;
  cin >> a;
  cout << "result : " << x->a(a)->c() << endl;
  x->z->f();
  delete x;
  return 0;
}

虽然 Z 对象可以在 ~X() 上轻松释放,但我很好奇如何释放 Y 对象?因为我没有分配任何变量来保存它的内存地址。

顺便说一句,这样的术语是什么?x->a(a)->c()

谢谢你。:)

4

2 回答 2

4
// How to free Y instance ?
Y* a(int x) {
  Y* y = new Y(x);
  return y;
}

好吧,问题是从函数原型中并不清楚负责删除实例。但是由于只有调用者拥有实例的句柄,所以删除应该是被调用者的责任。这应该有据可查。但最好的方法是使用具有正确所有权语义的智能指针。在这种情况下,std::unique_ptr<Y>似乎是一个合适的匹配,并且仅使用它的事实就清楚地表明了意图,消除了对有关所有权的文档的需要:

std::unique_ptr<Y> a(int x)
{
  return std::unique_ptr<Y>( new Y(x) );
}
于 2013-03-10T21:05:25.007 回答
1

您正在从函数中返回内存,因此由调用者来删除它:

X x;

Y *ptr = x.a(5);

delete ptr;

希望你永远不必做这样的事情。如果必须,那么建议您使用智能指针,如 ashared_ptrunique_ptr

std::unique_ptr<Y> a(int x) {
  return std::unique_ptr<Y>(new Y(x));
}

有了这个,你永远不必担心删除实例,因为指针类的析构函数承担了这个责任。

于 2013-03-10T21:08:42.390 回答