почему определение метода с типом возвращаемого значения в качестве его класса не приведет к ошибке «неполный тип»

Насколько я знаю, при определении функции с типом возвращаемого объекта, в то время как класс находится только в состоянии прямого объявления, например:

class A;

// переадресация объявления как неполный тип

A foo(){...}

// ошибка: A является неполным типом
Я знаю, что он прекрасно работает, когда он имеет возвращаемый тип указателя или ссылку на этот объект.

Но когда я определяю метод с типом возвращаемого значения в качестве его класса:

class B{
public:
B foo(){...}
}

Работает отлично.

Я думаю, что при определении метода в определении класса класс по-прежнему является неполным типом.
Поэтому я думаю, что это вызовет ошибку, похожую на предыдущую, но это не так.
Кто-нибудь знает почему?

Я долго искал, прежде чем просить о помощи здесь.
(Я плохо разбираюсь в английском, поэтому мое описание может вас запутать. Извините за это.)

2

Решение

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

Можно объявить тип возврата B для одной из его функций-членов, даже если B является неполным в этой точке, как указано в C ++ 11 8.3.5 / 9:

Тип параметра или возвращаемого типа для определения функции не должен быть неполным типом класса (возможно, cv-квалифицированным) если только определение функции
вложен в член-спецификация для этого класса

Также хорошо создать экземпляр объекта типа B вернуться в тело функции; в определении класса класс считается завершенным в различных контекстах, включая тела функций, как указано в C ++ 11 9.2 / 2:

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

2

Другие решения

При определении методов внутри класса класс обрабатывается так, как если бы он был полным типом, иначе мы не смогли бы определить встроенные методы. Кроме того, если бы ваш класс A был неполным типом, то любопытно повторяющийся шаблон не будет работать. Рассмотрим следующий код:

template <typename T> struct base {};

struct derived : base<derived> {};  // We can use derived here
// without any "incomplete type"// errors.

Другими словами: просто так работает язык.

РЕДАКТИРОВАТЬ: См. Ниже Mike Seymour для соответствующего раздела стандарта C ++, который упоминает это поведение.

3

По вопросам рекламы [email protected]