C ++ Форвард Объявление класса? - PullRequest
1 голос
/ 04 сентября 2010

В .ч если у меня есть:

#pragma once

#include <xxxx.h>
#include "yyyy.h"

class AAAAAA;
class BBBBBB;

class ZZZZZZ
{
     public:

     // etc
 };

с использованием класса AAAAAA; вперед объявляет класс правильно?

Зачем это делать?

Это нужно?

Каковы преимущества? Недостатки?

Ответы [ 4 ]

3 голосов
/ 04 сентября 2010

Если вы ссылаетесь на класс по ссылке или по указателю, компилятор должен знать, что он существует, но не более того.Поэтому все, что вам нужно сделать, это объявить его в прямом направлении.

Если файл вызывает методы класса или ссылается на экземпляры объекта (не ссылки или указатели), тогда определение этого типа должно быть вставлено с помощью #include.

В большой кодовой базе минимизация #include уменьшает время компиляции.

Перенаправленные объявления также помогают избежать циклических проблем #include.

3 голосов
/ 04 сентября 2010

Зачем это делать?

Поскольку компилятор знает только имена, которые были объявлены.Поэтому, если вы хотите использовать класс, вы должны объявить его.Но если его определение зависит от пользователя, может потребоваться предварительное объявление, если пользователь, в свою очередь, зависит не от определения класса, а только от его объявления (= name).

В частности, еслипользователю просто нужен указатель или ссылка, это не зависит от определения.Но в перечисленных случаях (которые не претендуют на исключительность, поскольку это стандартная ненормативная выдержка), пользователь зависит от определения класса T, если

  • определен объект типа T(3.1), либо
  • T используется в качестве типа объекта или типа элемента массива в выражении new (5.3.4), либо
  • применяется преобразование lvalue-в-значениеЗначение l, относящееся к объекту типа T (4.1) или
  • , выражение преобразуется (неявно или явно) в тип T (п. 4, 5.2.3, 5.2.7, 5.2.9, 5.4) или
  • выражение, которое не является константой нулевого указателя и имеет тип, отличный от void *, преобразуется в указатель типа на T или ссылку на T с использованием неявного преобразования (раздел 4), dynamic_cast(5.2.7) или static_cast (5.2.9), или
  • оператор доступа к члену класса применяется к выражению типа T (5.2.5), или
  • оператор typeid(5.2.8) или оператор sizeof (5.3.3) применяется к операнду типа T или
  • функция с типом возвращаемого значения или типом аргумента типа T определяется (3.1) или вызывается (5.2.2), или
  • определяется класс с базовым классом типа T (раздел 10),или
  • значение l типа T присваивается (5.17), или
  • объявление исключения имеет тип T, ссылку на T или указатель на T (15.3).

В этих случаях предварительное объявление будет не достаточным, и вам необходимо полностью его определить.

Это нужно?

Да, в случаях, когда это необходимо, это необходимо.В следующем случае это так, потому что оба класса ссылаются друг на друга.

class A;

class B {
  // forward declaration needed
  void f(A);
};

class A {
  void f(B);
};

// "- a function with a return type or argument type of type T is defined"
void B::f(A) {

}

Для определения функции-члена требуется не только объявление, но и определение класса A.

Каковы преимущества?Недостатки?

Преимущества в том, что ваша программа компилируется.Недостатком является то, что вы загрязнили прицел еще одним именем.Но это неизбежное зло этого.

0 голосов
/ 04 сентября 2010

Предварительные объявления необходимы, когда классы ссылаются друг на друга. Вот простой случай:

class A;

class B {
     void f(A&);
};

class A {
     void f(B&);
};

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

0 голосов
/ 04 сентября 2010

Если вы собираетесь ссылаться только на этот тип, нет необходимости извлекать весь заголовок, в котором он определен, просто используйте предварительное объявление, которое сообщает компилятору «это определено», так что компилятор, когда он использует егов этом файле, и не может распознать символ, не волнует вас.Это одна из тех вещей «я знаю, что я делаю».

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