Error c2027 использование неопределенного типа

I am running into below error - when I just provide the definition of class first and then declare it later. My understanding was as long as we do that as I have done numerous times for function

When you declare a summary of something before using it, this is called a forward declaration.

When making a forward declaration to a function, the compiler has everything it needs in order to parse code which invokes that function: the name of the function, the type returned, the number of arguments, and the type of each argument.

But when making a forward declaration to a class, the compiler only knows that this particular symbol (generic_iterator in your case) is a class. Subsequently, the only thing you can do with it before it has been fully defined is to declare a pointer to it. (And people with more knowledge of C++ than me might know one or two additional arcane uses.) You cannot invoke any of its members, because the compiler does not yet know its structure. Your code is trying to invoke the constructor of your forward-referenced class, but the compiler does not know of any such constructor yet.

I do not know of any easy way to resolve this problem. Others might have some better solutions, but the way I tend to resolve this problem is by moving all of the code that needs to access members of a forwardly declared class from the .h file to the .cpp file. So, in your case, in the .h file I would simply write iterator begin(); and then in the .cpp file I would write generic_iterator darray::begin() {return iterator(ptrarray); }.

This would compile, because at that moment the complete class definition of generic_iterator is known.

Я сталкиваюсь с ошибкой ниже — когда я просто предоставляю определение класса, а затем объявляю его позже. Мое понимание было до тех пор, пока мы делаем это, поскольку я много раз делал для определения функции, компилятор понимает это, но, похоже, мое понимание ошибочно, если кто-то поможет мне понять, что недостает в понимании того, как объявлять класс.

error C2027: use of undefined type 'generic_iterator'
note: see declaration of 'generic_iterator

Не работает — ошибка показанная выше

#include <iostream>
class generic_iterator;
class darray
{
public:
typedef generic_iterator iterator;
darray();
darray(int size);
~darray();
int& at(int index);
int& operator [](int i);
int* data(void);
bool empty();
void fill(int val);
void print();
size_t max_size();
iterator begin() {return iterator(ptrarray); }
iterator end() { return iterator(ptrarray + size); }

private:
int *ptrarray;
int num_elements;
int size;
};

class generic_iterator
{
public:
generic_iterator(int *ptr);
~generic_iterator();
generic_iterator& operator++();     // pre-increment
generic_iterator operator++(int);    // post-increment
private:
int *iptr;
};

Работает : Когда весь класс объявлен первым

class generic_iterator
{
public:
generic_iterator(int *ptr);
~generic_iterator();
generic_iterator& operator++();     // pre-increment
generic_iterator operator++(int);    // post-increment
private:
int *iptr;
};

class darray
{
public:
typedef generic_iterator iterator;
darray();
darray(int size);
~darray();
int& at(int index);
int& operator [](int i);
int* data(void);
bool empty();
void fill(int val);
void print();
size_t max_size();
iterator begin() {return iterator(ptrarray); }
iterator end() { return iterator(ptrarray + size); }

private:
int *ptrarray;
int num_elements;
int size;
};

3

Решение

Когда вы объявляете резюме чего-либо перед его использованием, это называется предварительная декларация.

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

Но, делая прямое объявление классу, компилятор знает только, что этот конкретный символ (generic_iterator в вашем случае) это класс. Впоследствии, единственное, что вы можете сделать с ним до того, как оно будет полностью определено, это объявить указатель на него. (И люди с большим знанием C ++, чем я, могут знать одно или два дополнительных тайных использования.) Вы не можете вызывать ни одного из его членов, потому что компилятор еще не знает его структуру. Ваш код пытается вызвать конструктор вашего класса с прямой ссылкой, но компилятор пока не знает ни одного такого конструктора.

Я не знаю ни одного простого способа решить эту проблему. У других могут быть более удачные решения, но я стараюсь решить эту проблему путем перемещения всего кода, который необходим для доступа к членам заранее объявленного класса, из .h подать в .cpp файл. Итак, в вашем случае, в .h файл я бы просто написал iterator begin(); а затем в .cpp файл я бы написал generic_iterator darray::begin() {return iterator(ptrarray); },

Это скомпилируется, потому что на тот момент полное определение класса generic_iterator известен.

2

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

Компилятор должен знать определение класса generic_iterator чем занимается анализ этих определений функций

iterator begin() {return iterator(ptrarray); }
iterator end() { return iterator(ptrarray + size); }

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

Примите во внимание, что было бы правильно объявить оператор постоянного индекса вместе с оператором непостоянного значения. Например

int& operator [](int i);
const int& operator [](int i) const;

или же

int& operator [](int i);
int operator [](int i) const;

Также попробуйте использовать классификатор const с функциями-членами, которые не изменяют сам объект, как, например, empty или же max_size или, может быть print

bool empty() const;
void print() const;
size_t max_size()const;

3

Содержание

  1. ошибка C2027: использование неопределенного типа — как объявить класс
  2. Решение
  3. Другие решения
  4. ошибка C2027: использование неопределенного типа с несколькими файлами
  5. Решение
  6. Другие решения
  7. Ошибка C ++ C2027: использование неопределенного типа ‘second’ (Friend Class)
  8. 4 ответа
  9. ошибка C2027: использование неопределенного типа — как объявить класс
  10. 2 ответа
  11. Неполный тип: использование класса до определения или прямого объявления
  12. Решение

ошибка C2027: использование неопределенного типа — как объявить класс

Я сталкиваюсь с ошибкой ниже — когда я просто предоставляю определение класса, а затем объявляю его позже. Мое понимание было до тех пор, пока мы делаем это, поскольку я много раз делал для определения функции, компилятор понимает это, но, похоже, мое понимание ошибочно, если кто-то поможет мне понять, что недостает в понимании того, как объявлять класс.

Не работает — ошибка показанная выше

Работает : Когда весь класс объявлен первым

Решение

Когда вы объявляете резюме чего-либо перед его использованием, это называется предварительная декларация.

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

Но, делая прямое объявление классу, компилятор знает только, что этот конкретный символ ( generic_iterator в вашем случае) это класс. Впоследствии, единственное, что вы можете сделать с ним до того, как оно будет полностью определено, это объявить указатель на него. (И люди с большим знанием C ++, чем я, могут знать одно или два дополнительных тайных использования.) Вы не можете вызывать ни одного из его членов, потому что компилятор еще не знает его структуру. Ваш код пытается вызвать конструктор вашего класса с прямой ссылкой, но компилятор пока не знает ни одного такого конструктора.

Я не знаю ни одного простого способа решить эту проблему. У других могут быть более удачные решения, но я стараюсь решить эту проблему путем перемещения всего кода, который необходим для доступа к членам заранее объявленного класса, из .h подать в .cpp файл. Итак, в вашем случае, в .h файл я бы просто написал iterator begin(); а затем в .cpp файл я бы написал generic_iterator darray::begin() ,

Это скомпилируется, потому что на тот момент полное определение класса generic_iterator известен.

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

Компилятор должен знать определение класса generic_iterator чем занимается анализ этих определений функций

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

Примите во внимание, что было бы правильно объявить оператор постоянного индекса вместе с оператором непостоянного значения. Например

Также попробуйте использовать классификатор const с функциями-членами, которые не изменяют сам объект, как, например, empty или же max_size или, может быть print

Источник

ошибка C2027: использование неопределенного типа с несколькими файлами

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

Я работаю над проектом, где файл заголовка mips_cpu.h с определенным API дается. Я намерен разработать его реализацию без изменения файла заголовка. Этот API включает структуру, объявленную в файле mips_cpu.cpp как:

struct mips_cpu_impl;
typedef struct mips_cpu_impl *mips_cpu_h;

Затем я определил эту структуру в mips_cpu.cpp как:

Проблема возникает при использовании этой структуры в другом файле mips_cpu_instruction.cpp , Когда у меня есть этот код:

state затем выдает ошибку: использование неопределенного типа ‘mips_cpu_imps’

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

Решение

Проблема в том, что файл mips_cpu_instruction.cpp ничего не знает о struct mips_cpu_imps потому что это, вероятно, включает в себя .h файл, который вы не можете коснуться ( mips_cpu.h ), но, конечно, не .cpp файл, в котором определена эта структура ( mips_cpu.cpp ). Вы можете добавить объявление в mips_cpu_instruction.cpp , но тогда у вас возникнет проблема, если бы в проекте были другие файлы, использующие эту структуру, потому что вам также нужно было бы определить ее там, а при связывании вы получите несколько объявлений одной и той же структуры.

Лучшим решением было бы добавить его в файл, который вы не можете изменить, но так как вы не можете изменить его, вам нужно обойти это. Я бы создал другую .h файл, используя включать охранников защитить код от многократного включения, и тогда я бы смело #include этот новый .h файл в верхней части каждого .cpp файл, который нуждается в этом. Тогда это будет определено везде и только один раз.

В конце концов, это будет означать, что для использования этих API вы должны будете включить 2 .h файлы: тот, который вы не можете коснуться, и новый. Если вы не хотите включать 2 файла каждый раз, вы можете даже решить #include mips_cpu.h внутри вашего нового файла, и тогда вам просто нужно #include новый, и вы можете в значительной степени забыть о своем неизменяемом файле.

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

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

Чтобы позволить вам преодолеть проблему программирования, не помогая вам делать домашнее задание напрямую, введите:

Источник

Ошибка C ++ C2027: использование неопределенного типа ‘second’ (Friend Class)

Я изучаю функции друзей (C ++), но не могу понять, почему этот код не работает. Я понял это

ошибка: «ошибка C2027: использование неопределенного типа« второй »». (строка номер 6)

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

4 ответа

Для доступа к second::fun требуется полное определение second . Это можно исправить, если вы измените порядок , в котором вы определяете эти классы, и вместо этого объявите вперед test . Но опять же, b.j требует определения test , поэтому вам придется отделить и отложить определение second::fun :

Когда компилятор читает эту строку

Он не знает, действительно ли второй класс имеет член данных fun . Чтобы убедиться, что эта строка верна, компилятору необходимо определение класса second .

С другой стороны, определение функции fun должно знать, что класс test имеет член данных j .

Чтобы разрешить коллизию, вы можете написать так

У вас есть пара проблем с кодом. За

Для работы компилятор должен знать, что такое second . Поскольку это неполный тип, вы получите ошибку компилятора. Чтобы исправить это, вам нужно объявить second перед тестом. Это поднимает другую проблему, поскольку

Использует test . Чтобы исправить это, мы переадресуем объявление test , а затем объявим second . После изменения вам необходимо переместить фактическое определение функции из second и оставить его после test .

Источник

ошибка C2027: использование неопределенного типа — как объявить класс

У меня возникает ошибка ниже — когда я просто предоставляю определение класса сначала, а затем объявляю его позже. Мое понимание было до тех пор, пока мы это делаем, поскольку я много раз делал для определения функции, компилятор ее получает, но, похоже, мое понимание ошибочно, может кто-то помочь мне понять, что не хватает в понимании того, как объявить класс.

Не работает — ошибка, показанная выше

Работы: когда объявлен весь класс

2 ответа

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

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

Но при создании прямого объявления для класса компилятор знает только, что этот конкретный символ ( generic_iterator в вашем случае) является классом. Впоследствии единственное, что вы можете сделать с ним до того, как оно было полностью определено, — это объявить указатель на него. (И люди с большим знанием С++, чем я, могут знать одно или два дополнительных тайных использования.) Вы не можете вызывать ни одного из своих членов, потому что компилятор еще не знает его структуры. Ваш код пытается вызвать конструктор вашего класса с прямой ссылкой, но компилятор еще не знает какого-либо такого конструктора.

Я не знаю, какой простой способ решить эту проблему. Другие могут иметь несколько лучших решений, но способ, которым я склонен решить эту проблему, — это переместить весь код, который должен получить доступ к членам объявленного класса из файла .h в файл .cpp . Итак, в вашем случае в файле .h я просто напишу iterator begin(); , а затем в файле .cpp напишу generic_iterator darray::begin() .

Это скомпилируется, потому что в этот момент известно полное определение класса generic_iterator .

Источник

Неполный тип: использование класса до определения или прямого объявления

Я знаю, что мы не можем определить функции, принимающие неполный тип в качестве параметра, поэтому ожидается, что приведенный ниже код не скомпилируется с ошибка C2027: использование неопределенного типа ‘Derived’

По той же логике я бы ожидал, что компиляция завершится неудачно, когда test () получит объект Base, который до этого момента имеет неполный тип. Тем не менее, это не так, и следующий код прекрасно компилируется

Есть ли разница между неполным типом класса, который есть у нас во время определения класса, и незавершенным типом, предоставляемым предварительным объявлением?

Решение

Логика не та же самая. Разница в том, что в вашем втором примере функции Base::test() использует объекты своего класса Base (в отличие от полностью иностранного класса Derived ).

Язык дает особый подход к этой ситуации в 8.3.5 / 6 (C ++ 03)

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

Это правило можно рассматривать как «спутник» для другого подобного правила — того, которое говорит, что тип класса всегда рассматривается полностью (и как полный тип) из тел функций-членов класса, аргументов по умолчанию и списков инициализатора конструктора. См. 9.2 / 2 (C ++ 03)

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

Обратите внимание, что во всех других контекстах до закрытия > класс считается неполным

Источник

5 / 5 / 0

Регистрация: 27.11.2016

Сообщений: 74

1

24.06.2019, 14:56. Показов 1732. Ответов 16


Здравствуйте, товарищи!

Уже давно сталкиваюсь с одной надоедливой проблемой, но в последнее время она меня уже совсем достала.

Допустим, в моем проекте объявлены и определены штук 5 классов, каждому классу выделен свой хедер и срр-шник, выглядит это примерно так:

Файл Class1.h:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#pragma once
 
#include "Class2.h"
#include "Class3.h"
#include "Class4.h"
#include "Class5.h"
 
class Class1 
{
 
//Какая-то реализация
...
 
//Какие-то методы, которые могут принимать параметром объекты других классов Class1..5
 
};

Файл Class2.h:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#pragma once
 
#include "Class1.h"
#include "Class3.h"
#include "Class4.h"
#include "Class5.h"
 
class Class2 
{
 
//Какая-то реализация
...
 
//Какие-то методы, которые могут принимать параметром объекты других классов Class1..5
 
};

Файл Class3.h:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#pragma once
 
#include "Class1.h"
#include "Class2.h"
#include "Class4.h"
#include "Class5.h"
 
class Class3 
{
 
//Какая-то реализация
...
 
//Какие-то методы, которые могут принимать параметром объекты других классов Class1..5
 
};

Файл Class4.h:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#pragma once
 
#include "Class1.h"
#include "Class2.h"
#include "Class3.h"
#include "Class5.h"
 
class Class4 
{
 
//Какая-то реализация
...
 
//Какие-то методы, которые могут принимать параметром объекты других классов Class1..5
 
};

Файл Class5.h:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#pragma once
 
#include "Class1.h"
#include "Class2.h"
#include "Class3.h"
#include "Class4.h"
 
class Class5 
{
 
//Какая-то реализация
...
 
//Какие-то методы, которые могут принимать параметром объекты других классов Class1..5
 
};

При попытке компиляции такого чуда иногда появляются ошибки линковки/компиляции, но я пытаюсь их исправлять.
А попытки мои простые: дергать туда-сюда инклюды, из какого-то файла типа Class1..5.h удалить, в какой-то добавить…
ну и так дергать, пока не заработает. Да, понимаю, что это тупо, но, в принципе, оно компилировалось и работало нормально.

Пока я не добавил еще один класс. Теперь при попытке компиляции вылезает куча ошибок. Реально куча: от 40 до 250, в
зависимости от того, как я пытаюсь их исправить, как я переставляю инклюды, но оптимального порядка включения инклюдов
я найти так и не смог. Но и без инклюдов нельзя, без них вываливаются ошибки типа «необъявленный идентификатор» (что логично),
«недопустимый неполный тип», » :: должен указывать на пространство имен» и т.д. То есть практически в каждом хедере
у меня должны быть ссылки на все остальные файлы. Но в этом случае, как я уже отмечал, имею сотни ошибок типа С2027
«использование неопределенного типа» и других. Число ошибок несколько уменьшается при попытке «подружить» классы,
но все равно проект не компилируется.

Вопрос: как правильно стоит подключать файлы, если для работы их содержимого каждому требуются все остальные файлы?
В моем варианте имею кучу ошибок компиляции. При невключении файлов имею необъявленные идентификаторы и прочее.
Все директивы типа #pragma once стоят, пытался даже продублировать их через условную компиляцию, но не помогает.

Благодарю за внимание.

__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь



0



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

ПК работает медленно?

  • 1. Загрузите ASR Pro с веб-сайта
  • 2. Установите его на свой компьютер.
  • 3. Запустите сканирование, чтобы найти вредоносные программы или вирусы, которые могут скрываться в вашей системе.
  • Улучшите скорость своего компьютера сегодня, загрузив это программное обеспечение — оно решит проблемы с вашим ПК. г.

    Разве это не причина, которую вы ищете? Изучите другие вопросы, называемые прямым объявлением синтаксиса класса C ++, или проясните свой вопрос.

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

    Когда вы предварительно объявляете функцию, у компилятора есть все идеи, поэтому ему необходимо проанализировать код, который вызывает какую функцию: точное имя функции, какой-то тип возвращаемого имени, номер, который должен быть указывается в аргументах. , и, кроме того, введите de для каждого аргумента.

    Но когда вы явно объявляете каждый класс, какой-то компилятор знает только, что этот конкретный символ (в случае generic_iterator ) определенно является символом. Тогда единственная тема, которую вы можете сделать из-за этого, прежде чем она будет полностью определена, – это возможность успешно объявить указатель на нее. (И мы с большим знанием C ++, чем я должен знать об одном или двух различных подпольных приложениях.) Вы не можете вызвать все члены, потому что компилятор еще не знает их структуру. Ваш способ области видимости пытается вызвать конструктор с в настоящее время ранее указанным классом, но компилятор абсолютно еще не знает о таком конструкторе.

    error c2027 использование неопределенного типа

    Я еще не знаю простого способа решить эту проблему. У других, вероятно, будут лучшие решения, но я хочу исправить это, переместив весь, я бы сказал, код, который требуется для доступа к людям объявленного класса, в начало, связанное с .h >, непосредственно в < code> .cpp файл. В этом конкретном случае я мог бы просто написать iterator begin (); для файла .h , тогда я бы явно написал в файле .cpp , который, вероятно, я бы написал generic_iterator darray :: beginnce () return iterator (ptrarray ); .

    Это может помочь, поскольку на этом этапе отмечается полная персонификация программы generic_iterator .

    удовлетворен 15 ноя 15 в 21:36.

    47.8k 88 золотых значков 8181 серебряный знак 119119 бронзовых знаков

    KКомпилятор хочет понять определение группировки generic_iterator , если возможно, анализируя эти определения операций

    ПК работает медленно?

    ASR Pro — идеальное решение для ремонта вашего ПК! Он не только быстро и безопасно диагностирует и устраняет различные проблемы с Windows, но также повышает производительность системы, оптимизирует память, повышает безопасность и точно настраивает ваш компьютер для максимальной надежности. Так зачем ждать? Начните сегодня!

      начинать с () итератор return iterator (ptrarray);итератор give up () повторение + итератор (размер ptraarray); 

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

    Отметьте, что было бы правильно объявить каталог безжалостным, используя непостоянный оператор. По рассматриваемой ситуации

      int & оператор [] (int i);const int & master [] (int i) const; 
      int & оператор [] (int i);int сеть мобильного телефона [] (int i) const; 

    Также попробуйте использовать все квалификаторы const с функциями-членами, в которых никогда не изменяют сам объект, например, для наиболее подходящих empty или max_size вместе с, возможно, print

      unload bool () const;void print () const;size_t max_size () const; 

    ошибка c2027 использовать за неопределенным типом

    Создан 15 ноя в.

    232k

    ошибка c2027 использовать для неопределенного типа

    Улучшите скорость своего компьютера сегодня, загрузив это программное обеспечение — оно решит проблемы с вашим ПК. г.

    Here’s How To Fix Error C2027 With Simple Use Of Undefined Type
    Hier Können Sie Den Fehler C2027 Mit Einfacher Verwendung In Bezug Auf Einen Undefinierten Typ Beheben
    Ecco Come Risolvere I Problemi C2027 Con Il Semplice Utilizzo Di Un Tipo Non Definito
    Dit Is De Eenvoudigste Manier Om Fout C2027 Op Te Lossen Met Eenvoudig Verbruik Van Een Niet-gedefinieerd Type
    Voici Comment Corriger L’erreur C2027 Avec Une Utilisation Simple Dans Un Type Non Défini
    Aqui Está O Que Corrigir O Erro C2027 Com O Simples Uso De Tipo Indefinido
    정의되지 않은 유형을 사용하여 실수 C2027을 수정하는 방법은 다음과 같습니다.
    Så Här Blir Du Av Med Fel C2027 Med Enkel Användning Av Odefinierad Typ
    Oto Jak Naprawić Błąd C2027 Za Pomocą Prostego Użycia Niezdefiniowanego Typu
    Aquí Se Explica Cómo Corregir El Error C2027 Con El Uso Simple De Tipo Indefinido

    г.

    I am learning friend functions (C++) but I can not understand why this code does not work. I get this

    error: «error C2027: use of undefined type ‘second'». (line number 6)

    It is just an example of course (useless). I am trying to use a member function of another class as friend (just that function). I find some example in the web. But in one old post here someone said that a member function of another class cannot be friend of a class.. Is this true?

    #include<iostream>
    using namespace std;
    class second;
    
    class test
    {
        friend void second::fun(test &);
    public:
        int j = 89;
    private:
        int t = 12;
    };
    
    class second
    {
    public:
        void fun(test &b)
        {
            cout << "Try " << b.j << endl;
        }
        int a = 29;
    private:
        int u = 10;
    };
    
    int main()
    {
        test b;
        second one;
        one.fun(b);
        return 0;
    }
    

    asked Dec 10, 2015 at 16:52

    user5507798's user avatar

    To access second::fun, a complete definition of second is required. You can fix this if you reverse the order in which you define these classes and forward-declare test instead. But again, b.j requires test to be defined, so you’ll have to separate and postpone the definition of second::fun:

    #include<iostream>
    using namespace std;
    class test;
    
    class second
    {
    public:
        void fun(test &b); // test must be declared for using a reference to it
        int a = 29;
    private:
        int u = 10;
    };
    
    class test
    {
        friend void second::fun(test &); // second must be defined to access its member
    public:
        int j = 89;
    private:
        int t = 12;
    };
    
    void second::fun(test &b)
    {
        cout << "Try " << b.j << endl;   // test must be defined to access its member
    }
    
    int main()
    {
        test b;
        second one;
        one.fun(b);
        return 0;
    }
    

    answered Dec 10, 2015 at 16:56

    LogicStuff's user avatar

    LogicStuffLogicStuff

    19.3k6 gold badges53 silver badges73 bronze badges

    3

    Try the following:

    class test;
    
    class second
    {
    public:
        void fun(test &b);
        int a = 29;
    private:
        int u = 10;
    };
    
    class test
    {
        friend void second::fun(test &);
    public:
        int j = 89;
    private:
        int t = 12;
    };
    
    void second::fun(test &b)
    {
        cout << "Try " << b.j << endl;
    }
    

    answered Dec 10, 2015 at 16:59

    101010's user avatar

    101010101010

    41.3k10 gold badges92 silver badges163 bronze badges

    You have a couple issues with you code. For

    friend void second::fun(test &);
    

    To work the compiler must know what second is. Since it is an incomplete type you will get a compiler error. In order to fix that you need declare second before test. Doing that brings up another issue as

    second::fun(test &b)
    

    uses test. To fix this we would forward declare test and then declare second. After changing that you need to move the actual function definition out of second and have it after test.

    #include<iostream>
    using namespace std;
    class test;
    class second
    {
    public:
        void fun(test &b);
        int a = 29;
    private:
        int u = 10;
    };
    class test
    {
        friend void second::fun(test &);
    public:
        int j = 89;
    private:
        int t = 12;
    };
    
    void second::fun(test &b)
    {
        cout << "Try " << b.j << endl;
    }
    
    int main()
    {
        test b;
        second one;
        one.fun(b);
        return 0;
    }
    

    Live Example

    answered Dec 10, 2015 at 17:00

    NathanOliver's user avatar

    NathanOliverNathanOliver

    168k28 gold badges280 silver badges387 bronze badges

    When the compiler reads this line

    friend void second::fun(test &);
    

    it does not know whether the class second indeed has data member fun. To be sure that this line is correct the compiler needs the definition of the class second.

    On the other hand, the definition of the function fun must know that class test has data member j.

    To resolve the collision you can write the following way

    #include<iostream>
    using namespace std;
    
    class test;
    
    class second
    {
    public:
        void fun(test &b); // class test is already declared above
        int a = 29;
    private:
        int u = 10;
    };
    
    class test
    {
        friend void second::fun(test &); //class second is already defined above
    public:
        int j = 89;
    private:
        int t = 12;
    };
    
    void second::fun(test &b)
    {
        cout << "Try " << b.j << endl; // class test is already defined above
    }
    
    int main()
    {
        test b;
        second one;
        one.fun(b);
        return 0;
    }
    

    answered Dec 10, 2015 at 17:02

    Vlad from Moscow's user avatar

    Vlad from MoscowVlad from Moscow

    287k23 gold badges179 silver badges323 bronze badges

    2

    I am learning friend functions (C++) but I can not understand why this code does not work. I get this

    error: «error C2027: use of undefined type ‘second'». (line number 6)

    It is just an example of course (useless). I am trying to use a member function of another class as friend (just that function). I find some example in the web. But in one old post here someone said that a member function of another class cannot be friend of a class.. Is this true?

    #include<iostream>
    using namespace std;
    class second;
    
    class test
    {
        friend void second::fun(test &);
    public:
        int j = 89;
    private:
        int t = 12;
    };
    
    class second
    {
    public:
        void fun(test &b)
        {
            cout << "Try " << b.j << endl;
        }
        int a = 29;
    private:
        int u = 10;
    };
    
    int main()
    {
        test b;
        second one;
        one.fun(b);
        return 0;
    }
    

    asked Dec 10, 2015 at 16:52

    user5507798's user avatar

    To access second::fun, a complete definition of second is required. You can fix this if you reverse the order in which you define these classes and forward-declare test instead. But again, b.j requires test to be defined, so you’ll have to separate and postpone the definition of second::fun:

    #include<iostream>
    using namespace std;
    class test;
    
    class second
    {
    public:
        void fun(test &b); // test must be declared for using a reference to it
        int a = 29;
    private:
        int u = 10;
    };
    
    class test
    {
        friend void second::fun(test &); // second must be defined to access its member
    public:
        int j = 89;
    private:
        int t = 12;
    };
    
    void second::fun(test &b)
    {
        cout << "Try " << b.j << endl;   // test must be defined to access its member
    }
    
    int main()
    {
        test b;
        second one;
        one.fun(b);
        return 0;
    }
    

    answered Dec 10, 2015 at 16:56

    LogicStuff's user avatar

    LogicStuffLogicStuff

    19.3k6 gold badges53 silver badges73 bronze badges

    3

    Try the following:

    class test;
    
    class second
    {
    public:
        void fun(test &b);
        int a = 29;
    private:
        int u = 10;
    };
    
    class test
    {
        friend void second::fun(test &);
    public:
        int j = 89;
    private:
        int t = 12;
    };
    
    void second::fun(test &b)
    {
        cout << "Try " << b.j << endl;
    }
    

    answered Dec 10, 2015 at 16:59

    101010's user avatar

    101010101010

    41.3k10 gold badges92 silver badges163 bronze badges

    You have a couple issues with you code. For

    friend void second::fun(test &);
    

    To work the compiler must know what second is. Since it is an incomplete type you will get a compiler error. In order to fix that you need declare second before test. Doing that brings up another issue as

    second::fun(test &b)
    

    uses test. To fix this we would forward declare test and then declare second. After changing that you need to move the actual function definition out of second and have it after test.

    #include<iostream>
    using namespace std;
    class test;
    class second
    {
    public:
        void fun(test &b);
        int a = 29;
    private:
        int u = 10;
    };
    class test
    {
        friend void second::fun(test &);
    public:
        int j = 89;
    private:
        int t = 12;
    };
    
    void second::fun(test &b)
    {
        cout << "Try " << b.j << endl;
    }
    
    int main()
    {
        test b;
        second one;
        one.fun(b);
        return 0;
    }
    

    Live Example

    answered Dec 10, 2015 at 17:00

    NathanOliver's user avatar

    NathanOliverNathanOliver

    168k28 gold badges280 silver badges387 bronze badges

    When the compiler reads this line

    friend void second::fun(test &);
    

    it does not know whether the class second indeed has data member fun. To be sure that this line is correct the compiler needs the definition of the class second.

    On the other hand, the definition of the function fun must know that class test has data member j.

    To resolve the collision you can write the following way

    #include<iostream>
    using namespace std;
    
    class test;
    
    class second
    {
    public:
        void fun(test &b); // class test is already declared above
        int a = 29;
    private:
        int u = 10;
    };
    
    class test
    {
        friend void second::fun(test &); //class second is already defined above
    public:
        int j = 89;
    private:
        int t = 12;
    };
    
    void second::fun(test &b)
    {
        cout << "Try " << b.j << endl; // class test is already defined above
    }
    
    int main()
    {
        test b;
        second one;
        one.fun(b);
        return 0;
    }
    

    answered Dec 10, 2015 at 17:02

    Vlad from Moscow's user avatar

    Vlad from MoscowVlad from Moscow

    287k23 gold badges179 silver badges323 bronze badges

    2

    нужна помощь с классами

    Raf_Tank Дата: Среда, 01 Февраля 2017, 15:58 | Сообщение # 1

    был не раз

    Сейчас нет на сайте

    Столкнулся с такой проблемой, что ниже стоящий класс не может использовать выше стоящий класс как тип данных, хотя я и прописал перед ним
    class UpperClassName; Вот скрин для понимания.
    http://s1.uploadpics.ru/images/-yCmgfdmlf.png
    Подскажите пожалуйста что не так.
    Saitei Дата: Среда, 01 Февраля 2017, 16:13 | Сообщение # 2

    старожил

    Сейчас нет на сайте

    Цитата Raf_Tank ()

    Подскажите пожалуйста что не так.

    Проблема в том, что реализация Bullet находится снизу. Очевидно же: использование неопределённого типа «Bullet»

    Raf_Tank Дата: Среда, 01 Февраля 2017, 17:06 | Сообщение # 3

    был не раз

    Сейчас нет на сайте

    Цитата Saitei ()

    Проблема в том, что реализация Bullet находится снизу. Очевидно же: использование неопределённого типа

    Это я вижу, я не совсем корректно поставил вопрос. Правильнее будет спросить как решить эту проблему без сдвига классов? Я вообще не изучал с++ ни в школе, ни где-либо ещё, учусь по видеоурокам. Так вот в одном из таких уроков была похожая ситуация с двумя классами, и данную проблему решили таким простым путём, как своего рода «переопределение» класса выше. Как я и сделал, над классом Player есть строка, которая якобы должна дать понять компилятору, что где-то в коде есть этот самый класс Bullet, но почему-то не работает…

    Gudleifr Дата: Среда, 01 Февраля 2017, 17:26 | Сообщение # 4

    почти ветеран

    Сейчас нет на сайте

    Raf_Tank, не забывайте: C++ — это только «C для убогих». То, что не работает в C, то не сработает и в C++.
    Что у Вас происходит в ошибочной строчке? Компилятор пытается подставить в код операцию «зафигачить параметр». Для этого нужно знать «размер параметра», иначе «зафигачивание» не работает. Размер же «Bullet» на этот момент не известен, известно только, что это класс, а сколько в нем полей — неизвестно. В C, конечно, никакой идиот не будет пытаться передавать целиком структуру данных (а в C++ — пожалуйста), а ограничится передачей указателя. Указатель-то всегда имеет одинаковый «размер» и «зафигачивается» без проблем. Для передачи указателя на элемент класса предварительного «объявления без определения» достаточно, для передачи элемента класса целиком — нет. Тем более, что Вы не только передали элемент целиком, но и пытаетесь получить доступ к его кусочку «bx», о котором уж точно еще ничего не известно.

    P.S. За пользование видеокурсами и выкладывание листинга в виде картинки надо было бы карму попортить.



    Быдлокодеры любят повторять: «логика, убивающая мозг»,- когда их пытаются заставить программировать.

    Сообщение отредактировал GudleifrСреда, 01 Февраля 2017, 20:22

    dalikivug Дата: Среда, 01 Февраля 2017, 20:16 | Сообщение # 5

    почетный гость

    Сейчас нет на сайте

    тс стоит обротить внимание на C#, чтобы уменьшить последующее кол-во вопросов ^_^
    LP Дата: Четверг, 02 Февраля 2017, 01:22 | Сообщение # 6

    частый гость

    Сейчас нет на сайте

    Raf_Tank, в следующий раз выкладывай код не картинкой а текстом в теге [_code]твой код[/code] без «_» перед code. И копируй код ошибки ниже.
    Без сдвига классов только указателями, выложи листинг как полагается, покажут что и куда, а так — лень.

    Цитата Gudleifr ()

    P.S. За пользование видеокурсами и выкладывание листинга в виде картинки надо было бы карму попортить.

    Вот тут согласен)

    Цитата dalikivug ()

    тс стоит обротить внимание на C#, чтобы уменьшить последующее кол-во вопросов

    Не слушай его))

    Сообщение отредактировал LPЧетверг, 02 Февраля 2017, 01:27

    Raf_Tank Дата: Четверг, 02 Февраля 2017, 05:39 | Сообщение # 7

    был не раз

    Сейчас нет на сайте

    Цитата Gudleifr ()

    Размер же «Bullet» на этот момент не известен, известно только, что это класс

    компилятор даже не знает что это класс, о чём говорит вторая ошибка…

    Добавлено (02 февраля 2017, 05:39)
    ———————————————

    Код

    #include <iostream>
    using namespace std;

    class Enemy{
    public:
    float ex;
    Enemy(float e){
    ex = e;
    }
    };
    class Bullet;
    class Player{
    public: float xx;
    void sum(Enemy e, Bullet b){
    xx = e.ex + b.bx;
    cout << xx;
    }

    };
    class Bullet{
    public:
    float bx;

    Bullet(float b){
    bx = b;
    }
    };

    int main()
    {
    bool a = 1;
    Enemy e1(1.25);
    Bullet b1(1.75);
    Player p1;
    p1.sum(e1, b1);
    return 0;
    }

    Ошибка    1    error C2027: использование неопределенного типа «Bullet»    c:проект1проект1main.cpp    18    1    Проект1
    Ошибка    2    error C2228: выражение слева от «.bx» должно представлять класс, структуру или объединение    c:проект1проект1main.cpp    18    1    Проект1

    Сообщение отредактировал Raf_TankЧетверг, 02 Февраля 2017, 05:39

    dalikivug Дата: Четверг, 02 Февраля 2017, 09:41 | Сообщение # 8

    почетный гость

    Сейчас нет на сайте

    Так:

    main.cpp

    или так:

    enemy.hpp

    bullet.hpp

    player.hpp

    main.cpp

    а еще лучше так

    enemy.hpp

    enemy.cpp

    bullet.hpp

    bullet.cpp

    player.hpp

    player.cpp

    main.cpp

    Сообщение отредактировал dalikivugЧетверг, 02 Февраля 2017, 09:44

    Raf_Tank Дата: Четверг, 02 Февраля 2017, 09:50 | Сообщение # 9

    был не раз

    Сейчас нет на сайте

    Цитата Raf_Tank ()

    Так:

    main.cpp

    или так:

    enemy.hpp

    bullet.hpp

    player.hpp

    main.cpp

    а еще лучше так

    enemy.hpp

    enemy.cpp

    bullet.hpp

    bullet.cpp

    player.hpp

    player.cpp

    main.cpp

    Спасибо большое! Получилось!

    Gudleifr Дата: Четверг, 02 Февраля 2017, 14:15 | Сообщение # 10

    почти ветеран

    Сейчас нет на сайте

    Цитата Raf_Tank ()

    компилятор даже не знает что это класс, о чём говорит вторая ошибка…

    Знает, но не может ни разместиь (нет размера), ни связать с bx (нет объявления bx).

    Цитата Raf_Tank ()

    Правильнее будет спросить как решить эту проблему без сдвига классов?

    Цитата Raf_Tank ()

    Получилось!

    Тот самый сдвиг классов и получился.

    Добавлено (02 февраля 2017, 14:15)
    ———————————————
    Правильнее, видимо, будет так:

    Код

    #include <iostream>
    using namespace std;

    class Thing{
    public: float ex;
    };

    class Enemy: public Thing{
    public:
    Enemy(float e){
    ex = e;
    }
    };

    class Player{
    public: float xx;
    void sum(Thing e, Thing b){
    xx = e.ex + b.ex;
    cout << xx << «n»;
    }
    };

    class Bullet: public Thing{
    public:
    Bullet(float b){
    ex = b;
    }
    };

    int main()
    {
    bool a = 1;
    Enemy e1(1.25);
    Bullet b1(1.75);
    Player p1;
    p1.sum(e1, b1);
    return 0;
    }



    Быдлокодеры любят повторять: «логика, убивающая мозг»,- когда их пытаются заставить программировать.

    Сообщение отредактировал GudleifrЧетверг, 02 Февраля 2017, 12:24

    • Страница 1 из 1
    • 1

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

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

    Но при создании прямого объявления для класса компилятор знает только, что этот конкретный символ (generic_iterator в вашем случае) является классом. Впоследствии единственное, что вы можете сделать с ним до того, как оно было полностью определено, — это объявить указатель на него. (И люди с большим знанием С++, чем я, могут знать одно или два дополнительных тайных использования.) Вы не можете вызывать ни одного из своих членов, потому что компилятор еще не знает его структуры. Ваш код пытается вызвать конструктор вашего класса с прямой ссылкой, но компилятор еще не знает какого-либо такого конструктора.

    Я не знаю, какой простой способ решить эту проблему. Другие могут иметь несколько лучших решений, но способ, которым я склонен решить эту проблему, — это переместить весь код, который должен получить доступ к членам объявленного класса из файла .h в файл .cpp. Итак, в вашем случае в файле .h я просто напишу iterator begin();, а затем в файле .cpp напишу generic_iterator darray::begin() {return iterator(ptrarray); }.

    Это скомпилируется, потому что в этот момент известно полное определение класса generic_iterator.

    Понравилась статья? Поделить с друзьями:
  • Error c2027 use of undefined type
  • Error c2026 string too big trailing characters truncated
  • Error c2011 переопределение типа class
  • Error c2011 timespec переопределение типа struct
  • Error c2001 newline in constant