的Google Style Guide for C++说,大约在智能指针的部分:“Google C++风格指南”中提到的对象所有者是什么?
- 我们更喜欢在哪些对象具有单一,固定的业主设计。
我不完全理解这句话。
- 什么是对象所有者?
- 它只是指针吗?
的Google Style Guide for C++说,大约在智能指针的部分:“Google C++风格指南”中提到的对象所有者是什么?
我不完全理解这句话。
对象的“所有者”不是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_) { }
};
这是类似的,但现在矢量隐藏我们的原始指针;不可能有两个Pictures
引用相同的指针。当图片被销毁时,我们负责销毁rawData数组。在这种情况下,图片拥有原始数据。
现在,你不要有使用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_ptr
,boost::scoped_ptr
/boost::scoped_array
或std::vector
(对于拥有的阵列)有助于防止出错。
继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();
}
好吧,'所有者'不是C++语言的实际部分。然而,在C++中,它是如何实现的。它只是指向对象的指针? – ashim 2011-12-31 16:39:40
@capoluca,'所有者'是一个概念,所以有多种方式来实现所有权关系。指针可能是所有权的一部分,但是指针也可以指向共享(非拥有)对象。 – bdonlan 2011-12-31 17:35:33
@bdonlan当我们不需要/希望复制语义和/或复制昂贵时会发生什么?我们是否只将所有内容作为shared_ptr传递? – aromero 2012-05-14 16:33:45