Предварительная декларация класса, функции - PullRequest
10 голосов
/ 03 декабря 2010

Когда прямое объявление функций работает в исходном файле (.cpp), почему то же самое не работает для классов?

Спасибо.

// main.cpp

void forwardDeclaredFunction() ; // This is correct 

class One ; // Why this would be wrong 

int One:: statVar = 10 ;

void
One :: anyAccess() {

 std::cout << "\n statVar:\t " << statVar ;
 std::cout << "\n classVar:\t" << classVar ;
}

class One {

 public:
  void anyAccess() ;
  static int statVar ;

 private:
  int  classVar ;

} ;


int main (int argc, char * const argv[]) {

 One *obj = new One ;

        return 0;
}

void forwardDeclaredFunction() {
}

Ответы [ 6 ]

12 голосов
/ 03 декабря 2010

Форвардное объявление может работать и для классов:

class Foo;

class Bar {
public:
    Foo *myFoo; // This has to be a pointer, thanks for catching this!
};

class Foo {
public:
    int value;
};

Приведенный выше код показывает предварительное объявление класса Foo с использованием переменной типа Foo * в другом классе (Bar), а затем фактическое определение класса Foo. C ++ не волнует, если вы оставите вещи нереализованными до тех пор, пока вы реализуете их перед использованием кода. Определение указателей на объекты определенного типа не означает «использование его кода».

Быстрый, грязный ответ, но я надеюсь, что это поможет.

Редактировать: Объявление переменной без указателя для класса, который не реализован, НЕ будет компилироваться, как указано в ответах. Это именно то, что я имел в виду под «использованием его кода». В этом случае конструктор Foo будет вызываться всякий раз, когда вызывается конструктор Bar, учитывая, что он имеет переменную-член типа Foo. Поскольку компилятор не знает, что вы планируете реализовать Foo позже, он выдаст ошибку. Извините за мою ошибку;).

5 голосов
/ 03 декабря 2010

Предварительная декларация class One; позволяет ссылаться на сам класс , но не на любого из его членов. Вы должны поместить все определения членов класса после полного объявления класса. (Или внутри, конечно.)

3 голосов
/ 03 декабря 2010

Поместите объявление члена вашего класса перед реализациями члена.

class One {

 public:
  void anyAccess() ;
  static int statVar ;

 private:
  int  classVar ;

} ;

int One:: statVar = 10 ;

void
One :: anyAccess() {

 std::cout << "\n statVar:\t " << statVar ;
 std::cout << "\n classVar:\t" << classVar ;
}
2 голосов
/ 03 декабря 2010

Компилятор читает материал от начала до конца и генерирует код по мере необходимости.(Некоторые компиляторы могут этого не делать, но они должны вести себя так, как будто они это сделали.) Но до того, как класс определен, компилятор не знает, что One::statVar или One::anyAccess должно существовать, или является ли функция виртуальной, статической, или что.Это необходимо знать, чтобы генерировать код.

2 голосов
/ 03 декабря 2010

Вы получаете сообщение об ошибке на int One:: statVar = 10 ; NOT в предварительном объявлении, что нормально.

Компилятору необходимо знать полное определение класса, прежде чем вы сможете определить статические члены, подобные этому -предварительное объявление недостаточно (оно должно быть в состоянии подтвердить, что тип является правильным из определения класса).

Вам нужно переместить определение статического атрибута ниже определения класса.

0 голосов
/ 07 января 2011

когда вы создаете 2 класса, и одна функция может получить доступ к данным из класса в другой класс, тогда это функция друга.

Объявление forword используется для определения, какой класс в следующем

классе abc.;

class xyz

{

элемент данных;

public:

friend void getdata ();

другая функция-член

}

class abc

{

элемент данных

public:

friend voidgetdata ();

}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...