Подтвердить что ты не робот

Передовая декларация класса, функции

Когда форвардные объявления функций работают в исходном файле (.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() {
}
4b9b3361

Ответ 1

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

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. С++ все равно, если вы оставите вещи нереализованными до тех пор, пока вы их реализуете, прежде чем использовать свой код. Определение указателей на объекты определенного типа не "использует его код".

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

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

Ответ 2

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

Ответ 3

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

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 ;
}

Ответ 4

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

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

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

Ответ 5

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

Ответ 6

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

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

класс abc;

класс xyz

{

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

общественности:

friend void getdata();

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

}

класс abc

{

член данных

общественности:

friend void getdata();

}