Google C ++风格指南中提到的对象所有者是什么?

时间:2011-12-31 04:34:11

标签: c++

Google Style Guide for C++在关于智能指针的部分中说:

  • 我们更喜欢具有单个固定所有者的设计。

我不完全理解这句话。

  • 什么是对象所有者?
  • 只是指针吗?

2 个答案:

答案 0 :(得分:3)

对象的“所有者”不是C ++语言的实际部分,而是一个概念工具 - 作为“所有者”的想法负责决定何时可以销毁对象。如果一个对象只有一个所有者,那么很容易弄清楚何时需要销毁该对象 - 只需看看所有者即可。然而,当一个对象被多个其他对象引用时,事情就不那么清楚 - 没有一个引用对象可以自己删除裁判对象,因为这会给其他引用者带来问题。因此,没有“单一,固定的所有者”。

举一些例子,考虑一个'图片'对象。

class Picture {
  char *rawData;
public:
  Picture(char *rawData_) : rawData(rawData_) { }
  Picture(const Picture &p) : rawData(p.rawData) { }
};

图片拥有rawData;正如我们从复制构造函数中看到的那样,让多个图片引用相同的数据非常容易。更好的版本可能如下:

class Picture {
  std::vector<char> rawData;
public:
  Picture(const std::vector<char> &rawData_) : rawData(rawData_) { }
};

这是类似的,但现在vector正在为我们隐藏原始指针;两个Pictures引用相同的指针是不可能的。我们负责在销毁图片时销毁rawData数组。在这种情况下,Picture拥有原始数据。

现在,您没有拥有来使用STL容器来拥有一个拥有的对象。你可以手动完成:

class Picture {
  size_t rawDataSize;
  char *rawData;

public:
  Picture(size_t rds, char *rd) {
    rawDataSize = rds;
    rawData = new char[rds];
    memcpy(rawData, rd, rds);
  }

  ~Picture() { delete [] rawData; }

  Picture(const Picture &pic) {
    rawDataSize = pic.rawDataSize;
    rawData = new char[rawDataSize];
    memcpy(rawData, pic.rawData, rawDataSize);
  }

  Picture& operator=(const Picture &pic) {
    delete [] rawData;
    rawDataSize = pic.rawDataSize;
    rawData = new char[rawDataSize];
    memcpy(rawData, pic.rawData, rawDataSize);
    return *this;
  }
};

这也是一种拥有关系; rawData数组'永久地'属于图片对象。所有访问都通过图片对象,并与图片对象一起被销毁。

通常,对于拥有关系,建议使用包装类来自动销毁,并防止意外复制。在我的第三个例子中,如果我忘记了复制构造函数或operator=,例如,会发生可怕的事情。使用包含类std::unique_ptrboost::scoped_ptr / boost::scoped_arraystd::vector(对于拥有的数组)有助于防止您犯错误。

答案 1 :(得分:2)

按照bdonlan的回答,一个C ++示例:

int main()
{
    // owner of 'obj' is main()
    Object *obj = new Object;

    // even if 'foo' receives an object, it is not its owner;
    // it shouldn't be responsible for destroying it
    foo(obj);

    // obj is still alive
    obj->DoSomething();

    // the owner should clean up what it created
    delete obj;
}

你问,

  

在c ++中,它是如何实现的。它只是指向对象的指针吗?

通常它会是一个指针,但并非总是如此。正如bdonlan所说,所有权是一个概念,一个对象的所有者将负责清理事后。参考的一个例子:

void foo(Object &obj) {}

int main()
{
    // owner of 'obj' is main()
    Object obj;
    obj.Init();

    foo(obj);

    // the owner is responsible for calling Cleanup()
    // it would be unnatural and confusing if Cleanup() 
    // was called in foo(), which is not the owner
    obj.Cleanup();
}