C ++: Инициализация переменной члена класса со ссылкой на другую переменную члена класса? - PullRequest
0 голосов
/ 09 ноября 2018

Я пытаюсь создать класс в c ++, вызываемый для хранения значений для ряда параметров, которые организованы как переменные-члены класса 'Planet' и класса 'Satellite', которые я хочу инициализировать со ссылкой на экземпляр «Планета». Здесь я приведу пример, где у меня есть класс PlanetCatalog с переменные-члены 'Планета Нептун' и 'Спутниковый тритон'.

class Planet {
    public:

    double a;

    Planet() {}

    void setParams(  const double a_) {
        a = a_;
    }
};


class Satellite {
    public:

    double b;

    Planet & planet;
    Satellite( Planet & planet_):planet(planet_) { }

    void setParams(const double b_) {
        b = b_;
    }
}; 

class PlanetCatalog {

    public:

    Planet neptune;
    Satellite triton(neptune);

    void setAll() {
        neptune.setParams(1.);
        triton.setParams(2.);
    }

};

Однако при компиляции я сталкиваюсь с ошибкой.

error: unknown type name 'neptune' 
    Satellite triton(neptune);

Возможно ли сохранить Планету и Спутник как переменные того же класса, что и я здесь? Если нет, то может ли кто-нибудь предложить лучший способ организации этой функциональности в c ++?

Ответы [ 2 ]

0 голосов
/ 09 ноября 2018

Использование круглых скобок для инициализации в классе заставляет компилятор рассматривать triton как нестатическое объявление функции-члена с neptune типом первого аргумента, вместо этого следует использовать синтаксис list-initialization :

Satellite triton{neptune};

Обратите внимание, что для этого нет необходимости определять PlanetCatalog конструктор.

0 голосов
/ 09 ноября 2018

Что случилось?

class PlanetCatalog {
public:
   ...
   Planet neptune;
   Satellite triton(neptune); //<-- Compiler sees this as a non-static member-function declaration
   ...

Из-за контекста этого оператора компилятор видит его как нестатическое объявление функции-члена и пытается найти такой тип с именем neptune в соответствующих пространствах имен ; Выдает ошибку, поскольку не может ее найти.


Опция 1 : Вы можете определить конструктор, который инициализирует для вас triton в его member-initialization-list

class PlanetCatalog {
public:
   ...
   Planet neptune;
   Satellite triton;

   PlanetCatalog() : triton(neptune) {}
   ...

Примечание: при использовании этой опции порядок членов данных вашего класса имеет значение , поскольку порядок инициализации элементов данных определяется порядком их объявления в классе, а не в порядке инициализации в member-initialization-list


Вариант 2 : еще одно простое решение - использовать инициализация копирования

Satellite triton = neptune;

Опция 3 : или инициализация списка

Satellite triton{neptune};

Варианты 2 и 3 предпочтительнее, поскольку они неявно форсируют порядок объявления.

...