最佳答案
对象的“所有者”并不是 C++ 语言的实际部分,而是一个概念工具 - “所有者”的想法负责决定何时可以销毁该对象。如果一个对象只有一个所有者,那么很容易找出该对象何时需要销毁 - 只需查看所有者即可。然而,当一个对象被多个其他对象引用时,事情就不太清楚了——没有一个引用对象可以单独删除引用对象,因为这会给其他引用者带来问题。因此不存在“单一、固定的所有者”。
举一些例子,考虑一个“图片”对象。
class Picture {
char *rawData;
public:
Picture(char *rawData_) : rawData(rawData_) { }
Picture(const Picture &p) : rawData(p.rawData) { }
};
图片不拥有rawData
;正如我们从复制构造函数中看到的那样,多个 Pictures 引用相同的数据太容易了。更好的版本可能如下所示:
class Picture {
std::vector<char> rawData;
public:
Picture(const std::vector<char> &rawData_) : rawData(rawData_) { }
};
这很相似,但是现在 vector 为我们隐藏了原始指针;两个 Picture
不可能引用同一个指针。当图片被销毁时,我们负责销毁 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
(对于自有数组)有助于防止您犯错误。
关于c++ - Google C++ 风格指南中提到的对象所有者是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8686293/