2016-07-24 2 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-класс вложен внутри другого. Я хотел бы иметь прямой доступ к Vec3.v [0] из высшего класса, как так:

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

таким образом, что Node.x фактически будет Node.vv [0], и я был бы в состоянии сделать это :

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

, но, к сожалению, нет. Выход я должен видеть это

2 2 

но то, что я действительно вижу

1 2 

Как вы можете видеть, я пытаюсь указать ссылочную й в списке инициализации конструктора узла в ссылку vx Vec3, и я даже инициализирую и вызываю конструктор Vec3 явно раньше. Тем не менее, n.x, похоже, ссылается на что-то другое. Возможно, таким образом это будет работать

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

но v.v является частным, и я действительно хочу, чтобы он остался таким.

Как я могу сделать эту работу так, как я планирую, не делая v.v public?

+0

Что это за 'главный'? Вы имели в виду 'int main()'? –

+0

Вы не инициализируете 'v' перед' x', просто изменив порядок в списке инициализаторов, потому что порядок членов в объявлении структуры определяет порядок инициализации. – phimuemue

+1

Если вы предоставляете 'public' ссылки на' private' данные, вы эффективно делаете эти данные 'public'. Единственное различие заключается в том, что одним из способов доступа к этим данным является «public» (ссылка), а другой (по фактическому члену) является «частным». В любом случае все, что вам нужно сделать, это использовать наследование, а не сдерживание. – Peter

ответ

3

Проблема с Node struct. Порядок инициализации класса не зависит от порядка инициализации, указанного в cosntructor, а скорее от порядка объявления переменных.

Исходно инициализируется double& с каким-то странным, унифицированным материалом, который является неопределенным поведением.

Изменить порядок деклараций

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

и вам будет хорошо.

+0

Да, это действительно решает проблему. Спасибо. – Motionbit

+0

@Motionbit Нет необходимости писать * спасибо * комментарий. Лучше принять мой ответ. – Zereges

Смежные вопросы