在Google c++风格指南中引用的对象所有者是什么?
What is the object owner referred to in the Google C++ Style Guide?
谷歌c++风格指南中关于智能指针的部分说:
- 我们更喜欢那些对象只有一个固定的所有者的设计。
我不完全理解这个句子。
- 对象所有者是什么?
- 它只是指针吗?
对象的"所有者"不是c++语言的实际组成部分,而是一个概念性工具——作为"所有者"的想法是负责决定何时可以销毁对象。如果一个对象只有一个所有者,那么很容易判断出该对象何时需要销毁——只要看看所有者就知道了。然而,当一个对象被多个其他对象引用时,事情就不那么清楚了——任何引用对象都不能单独删除仲裁对象,因为这会给其他引用者带来问题。因此,不存在"单一的、固定的所有者"。
举一些例子,考虑一个'picture'对象。
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数组。在本例中,图片拥有原始数据。
现在,您不需要使用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();
}
- 什么时候调用组成单元对象的析构函数
- 对RValue对象调用的LValue ref限定成员函数
- CMake-按正确顺序将项目与C运行时对象文件链接
- 空基优化子对象的地址
- 将对象数组的引用传递给函数
- 你能重载对象变量名本身返回的内容吗
- C++使用整数的压缩数组初始化对象
- 找不到成员对象:没有名为get_event()的成员,也处理多态性和向量
- 将对象移动到std::shared_ptr
- 堆分配的对象是否存在永不为空的唯一所有者?
- 如何在拥有的C++对象中安全地存储对所有者的引用?
- 如何为生存时间少于对象所有者的类组织对象所有权?
- 设计以访问对象所有者的元素
- 如何知道对象的所有者类
- 嵌套类对象的所有者
- 使用offsetof()从成员变量中获取所有者对象
- 获取预先创建的值的所有者对象?设计错误
- 在Google c++风格指南中引用的对象所有者是什么?
- 试图在Windows中更改互斥对象的所有者
- C++:对象通知其所有者销毁自身的通用方法