Доступ к методу объекта-члена в C ++ - PullRequest
0 голосов
/ 20 сентября 2011

Я пытаюсь получить доступ к методу объекта (myEOS.calc(...)) из метода объекта (myPlanet) другого класса, содержащего экземпляр первого класса (static EOS myEOS):

// class in class

class EOS {
  public:
    static float Y;
    float calc(float);
};
float EOS::calc(float x){
  return x;                      // some complicated calculation
}

class Planet {
  public:
    static EOS myEOS;            // want only one instance; cf. below
    static void setX(float* X);  // must be static; cf. below
};
void Planet::setX(float* X) {
  *X = myEOS.calc(*X);           // will give an error
}

int main(){
  Planet myPlanet;
}

Возвращает ошибку времени компоновки

In function `Planet::setX(float*)':
test.cpp:(.text+0x1a): undefined reference to `Planet::myEOS'
collect2: ld returned 1 exit status

Компиляция отдельно, с -c, классами и основной программой (с #include в основном файле) не дает ошибок;это похоже на ключ к решению, но я не вижу блокировки!

Кто-то знает, в чем проблема?Я надеюсь, что мое намерение ясно из того, что я имею, даже если есть какое-то фундаментальное заблуждение.Я думал, что я немного понял классы и перечитал учебники, но не видел обсуждения классов внутри классов (не вложенных классов).Мне не удалось найти аналогичный вопрос на этом сайте (откуда я обычно могу получить все ответы, которые мне нужны!).

Кстати, следуя чужому вопросу , добавивявные конструкторы (и правильная инициализация EOS в списке инициализаторов Planet) не убрали жалобу компилятора о «неопределенной ссылке на ключевое слово Planet::myEOS'" (this done without the static`).

Наконец, обратите внимание, что Planet::setX должен быть статическим, посколькууказатель на этот метод должен иметь сигнатуру «без класса», поскольку он передается функции, которая не может обрабатывать методы / классы:

 void (*fun_ptr)(float*) = & (Planet::setX);

Это также заставляет объект myEOS быть статическим (необходимобыть доступным из статической функции), и в любом случае инициализация EOS объектов стоит дорого.

Большое спасибо за помощь!

Ответы [ 2 ]

2 голосов
/ 20 сентября 2011
class Planet {
  public:
    static EOS myEOS;            // want only one instance; cf. below

Этот код говорит: "Компилятор: где-то позже будет глобальным EOS myEOS для этого класса. И компилятор говорит" хорошо "и делает свое дело, ожидая вас сказать ему, где находится глобальный EOS myEOS.
Затем приходит компоновщик, чтобы очистить беспорядок компилятора и говорит: «Я не могу найти myEOS, где вы поместили myEOS?» И отображает ошибку.

Вам нужно добавить куда-нибудь следующие строки в файл CPP:

float EOS::Y;
EOS Planet::myEOS;
2 голосов
/ 20 сентября 2011

Определить статическую переменную.

// class in class

class EOS {
  public:
    static float Y;
    float calc(float);
};
float EOS::calc(float x){
  return x;                      // some complicated calculation
}

class Planet {
  public:
    static EOS myEOS;            // want only one instance; cf. below
    static void setX(float* X);  // must be static; cf. below
};
void Planet::setX(float* X) {
  *X = myEOS.calc(*X);           // will give an error
}

// -------------------------
EOS Planet::myEOS;
float Planet::Y /* = <some value> if it makes sense*/;
// -------------------------

int main(){
  Planet myPlanet;
}

См. 9.4.2 Элементы статических данных в стандарте (98).

...