Google Style Guide for C++は、スマートポインタに関するセクションでは、こう述べています。私たちは、オブジェクトは、単一の、固定の所有者を持っているデザインを好むGoogle C++スタイルガイドでオブジェクト所有者とは何ですか?
- 。
私は文を完全に理解していません。
- オブジェクトの所有者とは何ですか?
- ポインタだけですか?
Google Style Guide for C++は、スマートポインタに関するセクションでは、こう述べています。私たちは、オブジェクトは、単一の、固定の所有者を持っているデザインを好むGoogle C++スタイルガイドでオブジェクト所有者とは何ですか?
私は文を完全に理解していません。
オブジェクトの「所有者」は、C++言語の実際の部分ではなく、むしろ概念的なツールです。オブジェクトが破壊される時期を決定するのは「所有者」という考え方です。オブジェクトに所有者が1人しかいない場合、オブジェクトをいつ破壊する必要があるのかを簡単に把握できます。所有者を見てください。オブジェクトが複数の他のオブジェクトによって参照されている場合、オブジェクトはあまり明確ではありません。参照オブジェクトはそれ自体で、他の参照者に問題を引き起こすため、審判オブジェクトを削除することはできません。だから、そこには、 "単一の固定所有者"がありません。
いくつかの例を挙げると、 '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_) { }
};
これは似ていますが、今のベクターは、私たちのために生のポインタを隠しています。 2つのポインタが同じポインタを参照することは不可能です。また、ピクチャが破棄されたときに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配列は永続的にピクチャオブジェクトに属します。すべてのアクセスは画像オブジェクトを通過し、画像オブジェクトと共に破棄されます。
一般に、所有関係では、ラッパークラスを使用して破壊を自動化し、誤ってコピーするのを防ぐことをお勧めします。私の3番目の例では、コピーコンストラクタまたは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
@capoluca、 'owner'は概念なので、所有関係を実装する方法はいくつでもあります。ポインタは所有権の一部であるかもしれませんが、ポインタは共有された(所有されていない)オブジェクトを指すこともできます。 – bdonlan
@bdonlanコピーのセマンティクスが不要/不要でコピーが高価な場合はどうなりますか?私たちはshared_ptrとしてすべてを渡しますか? – aromero