2016-07-24 3 views
0

私はそうのような、たとえば、それ以外のアクセスをより面倒になる内部変数への速記として参照を使用しての習慣を持っている:C++のプライベート変数への速記として参照

class Vec3 
{ 
    double v[3]; 

public: 

    // .x, .y and .z element access operators for convenience. 
    double& x; 
    double& y; 
    double& z; 

    Vec3() : x(v[0]), y(v[1]), z(v[2]) 
    { 

    } 
} 

この方法で、私はのためにすることができます例:

main 
{ 
    Vec3 v; 
    v.x = 1; 
    v.y = 2; 
    v.z = 3; 
} 

これまでのところすべてが完全に機能します。さて、このVec3クラスは他のクラスの中にネストされています。

struct Node 
{ 
    double &x; 
    Vec3 v; 
    Node() : v(Vec3()), x(v.x) {} 
}; 
Node.xが実際にNode.vv [0]になると、私はこれを行うことができるだろうということな

:私はそうのような上位クラスから[0] Vec3.vへの直接アクセスを持っているしたいと思います:

main 
{ 
    Node n; 
    n.v.x = 1; 
    n.x = 2; 
    std::cout << n.v.x << " " << n.x; 
} 

しかし、残念ながらいいえ。私が見てしなければならない出力が

2 2 

ですが、私が実際に見るものはあり

1 2 

あなたが見ることができるように、私が にノードコンストラクタの初期化リストを参照xを指すようにしようとしていますVec3の参照vx、そして私はさらに明示的にVec3のコンストラクタを初期化して呼び出します。それでも、n.xは何かを参照しているようです。おそらくこのように動作するだろう

Node() : x(v.v[0]) {} 

v.vはプライベートであり、私は本当にそれをそのままにしたい。

v.vを公開せずにこの作業を行う方法を教えてください。

+0

この「メイン」とは何ですか?あなたは 'int main()'を意味しましたか? –

+0

構造体宣言のメンバーの順序が初期化順序を決定するため、初期化子リストの順序を変更するだけで、 'x'の前に' v'を初期化しません。 – phimuemue

+1

'private'データへの' public'参照を提供している場合、そのデータを 'public'にすることが効果的です。唯一の違いは、そのデータにアクセスする手段の1つが「公開」(参照)であり、もう1つ(実際のメンバーによって)が「プライベート」であることです。いずれにせよ、あなたがする必要があるのは、封じ込めではなく、公開継承を使用することだけです。 – Peter

答えて

3

問題はNode構造体にあります。クラスの初期化順序は、cosntructorで指定された初期化の順序に依存するのではなく、変数の宣言の順序に依存します。

基本的にdouble&を初期化していますが、奇妙でユニット化されていないものがあります。これは未定義の動作です。

変更

struct Node 
{ 
    Vec3 v; 
    double &x; 
    Node() : v(Vec3()), x(v.x) {} 
}; 

への宣言の順序と、あなたは罰金になります。

+0

はい、これで問題は解決します。ありがとうございました。 – Motionbit

+0

@モーションビット*ありがとうございます*コメントを書く必要はありません。私の答えを受け入れる方が良い。 – Zereges

関連する問題