1. ホーム
  2. c++

[解決済み] メンバ変数をクラスメンバとして参照する

2023-01-26 11:47:13

質問

私の仕事場では、このスタイルが広く使われています。

#include <iostream>

using namespace std;

class A
{
public:
   A(int& thing) : m_thing(thing) {}
   void printit() { cout << m_thing << endl; }

protected:
   const int& m_thing; //usually would be more complex object
};


int main(int argc, char* argv[])
{
   int myint = 5;
   A myA(myint);
   myA.printit();
   return 0;
}

このイディオムを説明する名前はあるのでしょうか? 私は、大きな複雑なオブジェクトをコピーする際の大きなオーバーヘッドを防ぐためだと推測しています。

これは一般的に良い習慣でしょうか? このアプローチに落とし穴はありますか?

どのように解決するのですか?

<ブロッククオート

このイディオムを表す名前はあるのでしょうか?

UMLではaggregationと呼ばれています。構成と異なるのは、メンバーオブジェクトが 所有 を参照するクラスが所有しない点です。C++では、参照またはポインタを介して、2つの異なる方法で集約を実装することができます。

私は、大きな複雑なオブジェクトをコピーする際の大きなオーバーヘッドを防ぐためだと推測していますが?

いいえ、それはこれを使用する本当に悪い理由でしょう。集約の主な理由は、含まれるオブジェクトが含むオブジェクトによって所有されておらず、したがって、それらの寿命が束縛されていないことです。特に、参照されるオブジェクトの寿命は、参照するオブジェクトよりも長くなければなりません。それはずっと前に作成されたかもしれないし、コンテナの寿命の終わりを越えて生きているかもしれない。さらに、参照されるオブジェクトの状態は、クラスによって制御されるのではなく、外部から変更される可能性があります。もし参照先が const でない場合、クラスはその外側に住んでいるオブジェクトの状態を変更することができます。

これは一般的に良い方法でしょうか?このアプローチには何か落とし穴がありますか?

これはデザインツールです。ある場合には良いアイデアとなり、ある場合にはそうではありません。最も一般的な落とし穴は、参照を保持するオブジェクトの寿命が、参照されるオブジェクトの寿命を決して超えないようにすることです。もし、囲んでいるオブジェクトが参照 の後に の後に参照を使用した場合、未定義の動作をすることになります。一般的には集約よりも合成を優先した方が良いのですが、必要であれば他のツールに劣らず良いものです。