15

C++ では、メソッドはオブジェクトまたはオブジェクトへのポインターを返す必要がありますか? どのように決定するのですか?オペレーターだったら?どのように定義できますか?

もう 1 つ - ポインターがベクトルになった場合、返された後にそのサイズを確認するにはどうすればよいですか? そして、私が思うようにそれが不可能な場合、この制限なしで配列を正しく返すにはどうすればよいですか?

4

3 に答える 3

10

C++ では、メソッドはオブジェクトまたはオブジェクトへのポインターを返す必要がありますか? どのように決定するのですか?

C++11 以降、C++ にはムーブ セマンティクスがあります。これは、以前と同じように簡単で、値による戻りも高速であることを意味します。それがデフォルトのはずです。

オペレーターだったら?どのように定義できますか?

などの多くの演算子は、operator=通常、への参照を返します。*this

X& X::operator=(X rhs); 

通常のパターンに準拠したい場合は、各オペレーターについてそれを調べる必要があります (そうする必要があります)。ここから始めてください:演算子のオーバーロード

Ed S. が指摘したように、戻り値の最適化も適用されます (C++11 より前でも)。つまり、返すオブジェクトをコピーしたり移動したりする必要がないことがよくあります。

したがって、これがものを返す方法になりました。

std::string getstring(){ 
   std::string foo("hello");
   foo+=" world";
   return foo;
}

ここで foo オブジェクトを作成したという事実は、私の主張ではありませんreturn "hello world";

もう 1 つ - ポインターがベクトルになった場合、返された後にそのサイズを確認するにはどうすればよいですか? そして、私が思うようにそれが不可能な場合、この制限なしで配列を正しく返すにはどうすればよいですか?

同じことが、いくつかの例外を除いて、標準のすべてのコピー可能または移動可能な型 (これらは、 、 、およびそうでないものvectorsなど、ほとんどすべての型です) にも当てはまります。setsたとえば、 std::arrays は移動しても得られません。要素の量に比例して時間がかかります。unique_ptrそこで、コピーを避けるために a で返すことができます。

typedef std::array<int,15> MyArray;
std::unique_ptr<MyArray> getArray(){ 
  std::unique_ptr<MyArray> someArrayObj(new MyArray());
  someArrayObj->at(3)=5;
  return someArrayObj;
}

int main(){
  auto x=getArray();
  std::cout << x->at(3) <<std::endl; // or since we know the index is right: (*x)[3]
}

さて、これ以上書くことを避けるためにnew(まれなケースの専門家を除いて)、 と呼ばれるヘルパー関数を使用する必要がありますmake_unique。これは、例外の安全性に大きく役立ち、便利です。

std::unique_ptr<MyArray> getArray(){ 
  auto someArrayObj=make_unique<MyArray>();
  someArrayObj->at(3)=5;
  return someArrayObj;
}

より多くの動機と の (非常に短い) 実装についてはmake_unique、ここを見てください: make_unique と完全な転送

アップデート

make_uniqueC++14 標準の一部になりました。持っていない場合は、STL による提案から実装全体を見つけて使用できます。

それを行う方法のアイデアの例

于 2012-11-03T22:04:29.247 に答える
4

C ++では、メソッドはオブジェクトまたはオブジェクトへのポインターを返す必要がありますか?

デフォルトではオブジェクトを返す必要があります。通常の例外は、特定のクラスのサブクラスを返す関数であり、何も返さない場合は、関数1の有効なオプションです。

オペレーターの場合はどうなりますか?

演算子は参照またはオブジェクトを返します。オーバーロードされた演算子からポインタを返すことは技術的には可能ですが、通常は行われません。

そしてもう1つ、ポインタがベクトルになった場合、返された後のサイズをどのように確認できますか?

ベクトルのサイズを返すメンバー関数があるため、ベクトルではなく配列を意味していると思います。可変長配列のサイズを見つけることは確かに不可能です。std::vectorsize()

そして、それが不可能な場合、私が思うに、この制限なしに配列を正しく返すにはどうすればよいですか?

を使用する必要がありますstd::vector。これは、それに入る要素のサイズやタイプを制限するものではありません。


1この場合、NULLまたはnullptrC++11に戻ります。

于 2012-11-03T22:10:45.910 に答える
2

プレーンポインタを使用する特別な理由がない限り、常にメモリセーフなものを返します。すべてのケースの推定95%で、オブジェクトを返すだけで問題はなく、値による戻りは間違いなく標準的なことです(シンプル、効率的、優れています!)。

残りの5%は、ほとんどの場合、返されるオブジェクトがランタイムポリモーフィックである場合です。このようなオブジェクトは、スタックで発生するため、C++では値で返すことはできません。このような場合、新しいオブジェクトへのスマートポインタを返す必要があります。C++11では標準の選択はstd::unique_ptrです。オプションで何かを返したい場合もありますが、それはIMOの場合であり、ポインターなどではなく、特定のコンテナーのboost::optional場合です

于 2012-11-03T22:10:49.437 に答える