2011-11-25 5 views
0

これは2つの質問の1つです。C++ constをオブジェクトコンストラクタとメンバ関数で使用する

constを使用しようとすると、コンパイルエラーが発生します。

私が達成しようとしていること。

私のクラスのコンストラクタでは、私はオブジェクトへのポインタを渡します。私はconstを使用するようにオブジェクトのアドレスと値を変更したくありません。ここに私のコードは私が受けています

C* const m_mth1_ex; 
D* const m_mth2_ex ; 

エラーファイルクラスのヘッダに

クラスコンストラクタ

A::A(const B* const example): m_example(example) { 

     m_mth1_ex = m_example->method1(); 
     m_mth2_ex = m_example->method2(); 

} 

次のようになります。私は、初期化していますので、思った

error: uninitialized member 'A::m_mth1_ex' with 'const' type 'C* const' 
error: uninitialized member 'A::m_mth2_ex' with 'const' type 'D* const' 
error: assignment of read-only data-member 'A::m_mth1_ex' 
error: assignment of read-only data-member 'A::m_mth1_ex'  

をこれらのコンストラクタの値はこれで問題ありませんでしたが、ヘッダーファイルでそれらを宣言してconstはしませんそのように...

第2に、クラスBのメソッドはconstオブジェクトを返さないのですか?

最後に、メソッドはconst値とアドレスを持つクラスBから来ているので、これらのメソッドは変更できますか?

答えて

2

あなたはそれらの値を初期化していない、あなたはあります定数(読み込み専用)変数に値を代入することができないため、コンパイラに不平等を割り当てたりすることができます。クラスメンバーを初期化するには、コンストラクターの初期化リストを使用する必要があります。例:

また、メンバーの宣言の順序が重要なので、初期化の順序に注意してください。基本的にm_mth1_exがクラス内でm_exampleを宣言した場合、m_mth1_exは初期化リストの2番目に表示されますが、最初に初期化されるため、このコードは未定義の動作になります。この特定の例では

、これを書くために安全です:

A::A (const B *const example) 
    : m_example (example) 
    , m_mth1_ex (example->method1()) 
    , m_mth2_ex (example->method2()) 
{ 
} 

一般的に初期化リストおよびコンストラクタについて覚えておくべきもう一つの重要な事柄 - 例外がコンストラクタでスローされた場合、そのオブジェクトのデストラクタが呼び出されていません。したがって、method1()method2()がメモリを割り当てると呼び出すと、example->method2()がスローされると、example->method1()によって割り当てられたポインタが失われ、メモリリークが発生するため、このコードは不正です。 m_mth1_exm_mth2_exが何らかの種類のスマートポインタ(つまり、std::unique_ptr)。

+0

私はコンストラクタでこの非常に問題があると思います。私はあなたが言っているように、新しい演算子をオーバーロードするか、スマートポインタを使いやすくする必要があります: - D – MWright

3

初期設定割り当てを混同しています。前者はOK、後者はそうではありません。適切

使用の初期化:

A::A(const B* const example) 
: m_example(example), 
    m_mth1_ex(m_example->method1()), 
    m_mth2_ex(m_example->method2()) 
{ 
} 

(。あなたもメンバ変数の任意の特定の宣言順から自分を切り離すことexample->method1()を使用することを好むかもしれません)

0

constメンバーは初期化子リストで初期化されなければならないので、これはあなたがこれを行う必要があります意味:

A::A(const B* const example) 
: m_example(example), 
    m_mth1_ex = m_example->method1(), 
    m_mth2_ex = m_example->method2() 
{ 
} 

しかし、今はオブを注文に関してワームの巨大な缶を開けました初期化と保守性。メンバーは、記述したコードに従ってどのような順序で初期化するかにかかわらず、宣言の順序で初期化されます。したがって、m_meth1_exm_exampleの前に宣言されている場合、m_meth1_exが最初に初期化されます。

上記は機能しますが、おそらくコードに設計上の欠陥があります。私はより良いデザインを考え出すことに目を向けるでしょう。

関連する問題