Ошибка компилятора c2079

Цитата
Сообщение от kuroiryuu
Посмотреть сообщение

имеется описание классов в h-файле

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <map>
#include <set>
 
class Node;
class EdgeToNode;
class AdjacencyList;
 
typedef std::set<EdgeToNode> EdgesList;
typedef std::map<size_t, Node> NodesList;
 
class Node
{
public:
    Node(Node & node);
    Node(size_t key, std::wstring name) : key_(key), name_(name) {}
    ~Node();
    void AddDirected(Node node);
    void AddDirected(Node node, double cost);
    void AddDirected(EdgeToNode* edge);
    bool HasNeighbor(size_t key);
 
    inline size_t GetKey() const { return key_; }
    inline std::wstring GetName() const { return name_; }
private:
    size_t key_;
    std::wstring name_;
    AdjacencyList neighbors_; //ОШИБКА C2079!!!
};
 
class EdgeToNode
{
public:
    EdgeToNode(Node neighbor) : neighbor_(neighbor), cost_(1.0) {}
    EdgeToNode(Node neighbor, double cost) : neighbor_(neighbor), cost_(cost) {}
 
    inline double Cost() {return cost_;}
    inline Node Neighbor() const {return neighbor_;} //ОШИБКА C2558!!!
private:
    double cost_;
    Node neighbor_;
};
 
class AdjacencyList
{
public:
    virtual void Add(EdgeToNode e);
    virtual bool Contains(Node node);
    virtual bool Contains(EdgeToNode edge);
    inline EdgesList::iterator GetBeginEdge() {return list_.begin();}
    inline EdgesList::iterator GetEndEdge() {return list_.end();}
private:
    EdgesList list_;
};

при компиляции вылазит две ошибки
error C2558: class ‘Node’ : no copy constructor available or copy constructor is declared ‘explicit’
error C2079: ‘Node::neighbors_’ uses undefined class ‘AdjacencyList’

подскажите как бороться с этими ошибками?

по C2079 пробовал описать переменную Node::neighbors_ как

C++
1
AdjacencyList* neighbors_;

ошибка исчезла, но такое использование указателя не самый лучший способ, хотелось бы узнать как правильно в данной ситуации применить std::auto_prt<AdjacencyList>

У вас возникает ошибка потому, что в классе Node, когда вы определяете член класса AdjacencyList neighbors_;, компилятору не известно определение этого типа, то есть AdjacencyList Вы лишь предварительно объявили этот класс, но не определили, а компилятору, чтобы правильно определить класс Node, нужно знать размер класса AdjacencyList . То есть в этом месте тип AdjacencyList является неполным типом: компилятор не имеет информации о его размере. Когда же вы это поле заменили указателем, то компилятору не нужно само строение класса AdjacencyList , так как размер указателя компилятору в любом случае известен.

Во-втором случае при объявлении функции

C++
1
inline Node Neighbor() const {return neighbor_;}

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

то есть вы передаете не константную ссылку в качестве аргумента. А на временные объекты можно ссылаться только по константной ссылке. То есть компилятор не нашел подходящего конструктора копирования и выдал сообщение об ошибке.

То есть чтобы было понятно, ваша функция

C++
1
inline Node Neighbor() const {return neighbor_;}

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

C#
1
Node(const Node & node);

отсутствует!

I’m getting a compiler error with this header file:

#ifndef GAME1_H  
#define GAME1_H  
#include "GLGraphics.h"  
#include "DrawBatch.h"  
class GameComponent;  
class Game1 {  
private:  
    GLGraphics graphics;  
 GameComponent components;
 void updateDelegates();  
 void Run();  
};  

class GameComponent {  
private:  
 static int index;  
protected:  
 Game1 game;  
public:  
 GameComponent();  
 GameComponent(Game1 game);  
 void Update(int);  
 void Dispose();  
};  

class DrawableGameComponent: public GameComponent  
{  
private:  
 GLGraphics graphics;  
 DrawBatch drawBatch;  
public:   
 DrawableGameComponent();  
 DrawableGameComponent(Game1);  
 void Draw();  
};  

#endif

I see the problem is that Game1 needs the full definition of GameComponent, and that GameComponent needs the full definition of Game1. I had way too much trouble having these in separate headers, so that’s why they’re together. Is there any way I can do this without completely changing the implementation of one of the classes?

Thanks!

configurator's user avatar

configurator

40.9k14 gold badges82 silver badges115 bronze badges

asked Sep 26, 2010 at 4:06

Kalypso's user avatar

Think about the computer’s memory for a second here.

class B;

class A {
    byte aa;
    B ab;
};

class B {
    byte bb;
    A ba;
};

A x;

Now the question the compiler needs to answer is How much space should I reserve for x?

Let’s see. The first byte of x is byte aa;. Easy enough. That’s 1 byte.
Next comes B ab;. Let’s see what’s in there.
The first byte of x.ab is a byte bb;. That’s 2 bytes for x so far.
Next, is a A ba;. Let’s see what’s in there.
The first byte of x.ab.ba is a byte aa;. That’s 3 bytes for x so far.
And so on and so forth ad infinitum.
How big is x? The correct answer is of course *** OUT OF CHEESE ERROR ***.

The compiler doesn’t actually do this because it knows it can’t handle this case — so the syntax doesn’t allow circular containment in the first place.


Here’s a diagram of the contents of x in this example:
Diagram


UPDATE

Apparently, I forgot to include a solution here. Now that you understand what the problem is, the solution should be pretty simple. Use pointers. Either use a pointer from A to B and let B include A as it already does, or vice versa, or use two pointers. Then, you won’t have circular inclusion — if B doesn’t include a copy of A but just a pointer to it, that fixes the entire issue here.

Community's user avatar

answered Sep 26, 2010 at 4:20

configurator's user avatar

configuratorconfigurator

40.9k14 gold badges82 silver badges115 bronze badges

2

To do what you’re trying you’ll need to have a pointer to one of your classes rather than having it as a member.

For example:


class A;
class B;
class A {
   B b;
};

class B {
   A a;
};

This cannot work. It causes a circular structure. The constructor for A will call the constructor for B, which calls the constructor for A, and so on infinitely.

Instead, try:


class A;
class B;
class A {
   B *b;
};

class B {
   A *a;
};

A word of warning, though. If you are setting something up this way, there’s a pretty good chance your design is flawed. You should reconsider how you are solving your problem.

answered Sep 26, 2010 at 4:12

JoshD's user avatar

JoshDJoshD

12.5k3 gold badges43 silver badges53 bronze badges

At the risk of being off-topic: you can do this in C#, but unless the nested members are all load-on-demand you’ll get an immediate crash when you first instantiate either.

answered Sep 26, 2010 at 4:57

egrunin's user avatar

egruninegrunin

24.7k8 gold badges50 silver badges93 bronze badges

  • Remove From My Forums
  • Question

  • Good Morning all,

    I encountered a compiler error c2079 which said «use of undefined class/struc/union name» and am not sure how to solve it. The following is a simplified setup of classes inside my code:

    class a;

    class b {

    int b1;

    public :

    func1();

    }

    b::func1()

    {

    a aclass;

    aclass.a1()     <== this is where error c2079 come from. a1 is a public function of class a

    }

    I search Microsoft C++ compiler error web. It suggests that using pointer to a, instead of instance of a. So I changed

    a aclass      to     a * aclass = NULL;

    and

    aclass.a1()     to     aclass->a1();

    The compiler error changed to c2027 : use of undefined type ‘a’

    Any suggestions? Thanks for your help.

    Tom Lin

Answers

  • I would suggest to split class interface (to be put in .h files) from class implementation (to be put in .cpp file).

    So, you should have 4 files: 

    ClassA.h (header containing interface of class A)

    ClassA.cpp (implementation of class A)

    ClassB.h (header containing interface of class B)

    ClassB.cpp (implementation of class B)

    The implementation of B::func1 method should be put in ClassB.cpp file.

    The implementation of A::a1 method should be put in ClassA.cpp file.

    At the beginning of ClassB.cpp file, you should add a #include «ClassA.h» because you are using class A.

    See if this helps…

    Giovanni

    • Marked as answer by

      Thursday, May 6, 2010 6:41 PM

кто-то может помочь решить эту ошибку:

test.cpp(14): ошибка C2079: ‘x1’ использует undefined struct ‘x’
test.cpp(16): ошибка C2228: слева от «.x_x1» должен быть класс/структура/тип объединения

вот часть кода:

  struct  x  x1;
  ...
  x1.x_x1=y_x1;    

В unix программа компилирует и связывает без ошибок.
Благодарим за помощь,

Поделиться

Источник

1 ответ

С помощью только форвардной декларации вы можете определить указатель или ссылку на struct, вы не можете получить доступ к элементам (x1.x_x1) a struct.

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

например. следующее будет работать:

struct x {
  int x_x1;
};

struct  x  x1;
  ...
x1.x_x1=y_x1;

//или

#include "struct_x.h"
struct  x  x1;
  ...
x1.x_x1=y_x1;

где struct_x.h имеет:

struct x {
  int x_x1;
};

Kashyap

Поделиться

Ещё вопросы

  • 1LinqToCSV и десятичная глобализация
  • 0C ++ == перегрузка операторов (имплементации)
  • 0Логика при включении классов cpp в целевой проект c
  • 0Идентификатор триггера из таблицы A в таблицу B
  • 1Простой линейный график с альтаиром
  • 0Angularjs сбрасывает радиовход, если щелкнуть два раза подряд
  • 1Запрос разрешения камеры для WebView во время выполнения
  • 0Я пытаюсь запустить код C ++, который использует библиотеку Boost
  • 0Запретить ввод, пока не закончится первое действие?
  • 0Angularjs отображать HTML в специальных символах
  • 0Как написать предложение WHERE с Datetime, используя Sequelize в Node
  • 0Отображение определенного содержимого веб-сайта в веб-просмотр
  • 1Часто неправильно используется: аутентификация — фортификация
  • 0Передача значений из div, содержащего список с другой страницы
  • 1создание символической ссылки для strings.xml в папке значений
  • 0Рисование wxBitmapButton поверх wxStaticBitmap
  • 1В облачных функциях Firebase отказано в доступе
  • 0Enum не был объявлен
  • 0Неверное выражение пути. Должно быть StateFieldPathExpression
  • 1Коробки с картинками, дающие их изображения картинкам под ними
  • 0Удаление различий между объектами и массивами из разных массивов
  • 1Почему хорошо очищать SecurityContextHolder после завершения веб-запроса?
  • 1В Google Appmaker не удается получить requestAnimationFrame работает
  • 1Проблемы с конвертацией проекта Android Studio в новый ключ API
  • 0C ++ создает расширяемый массив с использованием указателей
  • 0Получение неопределенной переменной при попытке доступа к переменной из другого контроллера angularjs
  • 0Читать сырой сокет ip заголовок? C ++
  • 1AndroidAnnotations + Instant App — сгенерированный класс <applicationId> .R не найден
  • 1Блок перемещается только один раз на KEYDOWN (Python3.6 — Pygame)
  • 1Поезд Mobilnet V2 с трансферным обучением в Tensorflow
  • 1Размер JPEG в виде байтового массива для Web API
  • 1Куда вставить JScrollPane?
  • 0Найти номер, ближайший к другому числу с ++
  • 1как сохранить, а затем извлечь некоторую информацию из имен файлов в dataframe
  • 1VTK рендеринг 2D сетки в питоне
  • 0проверьте руководство, соответствующее вашей версии сервера MariaDB, на предмет правильного синтаксиса для использования рядом с ‘WHERE id =’ \ r \ n
  • 1Подсчет и список подключений в SignalR
  • 1Внедрение зависимостей только для базовой активности приводит к сбою дочерней активности
  • 1Создание биткойн-кошелька с открытым ключом
  • 0Как изменить строки со столбцами в матрице с одинаковой шириной?
  • 0динамическое window.find не работает с jQuery
  • 0Проверка формы symfony игнорирует сообщения
  • 0Центрированные значки с поплавком: слева
  • 1Matlab to Python Matrix Code
  • 0Как добавить значение в пользовательский атрибут с помощью JQuery?
  • 0Laravel пытается сохранить HTML в базе данных
  • 0Winsock2: «слушай» возвращается рано
  • 1SoftKeyboard накладывается на EditText — ConstraintLayout
  • 1Есть ли способ получения информации, отображаемой в работающем приложении Android?
  • 0Жасмин Тест — Неизвестный поставщик $ sceProvider

Сообщество Overcoder

description title ms.date f1_keywords helpviewer_keywords ms.assetid

Learn more about: Compiler Error C2079

Compiler Error C2079

11/04/2016

C2079

C2079

ca58d6d5-eccd-40b7-ba14-c003223c5bc7

Compiler Error C2079

‘identifier’ uses undefined class/struct/union ‘name’

The specified identifier is an undefined class, structure, or union.

This error can be caused by initializing an anonymous union.

The following sample generates C2079:

// C2079.cpp
// compile with: /EHsc
#include <iostream>
int main() {
   std::ifstream g;   // C2079
}

Possible resolution:

// C2079b.cpp
// compile with: /EHsc
#include <fstream>
int main( ) {
   std::ifstream g;
}

C2079 can also occur if you attempt to declare an object on the stack of a type whose forward declaration is only in scope.

// C2079c.cpp
class A;

class B {
   A a;   // C2079
};

class A {};

Possible resolution:

// C2079d.cpp
// compile with: /c
class A;
class C {};

class B {
   A * a;
   C c;
};

class A {};

Think about the computer’s memory for a second here.

class B;

class A {
    byte aa;
    B ab;
};

class B {
    byte bb;
    A ba;
};

A x;

Now the question the compiler needs to answer is How much space should I reserve for x?

Let’s see. The first byte of x is byte aa;. Easy enough. That’s 1 byte.
Next comes B ab;. Let’s see what’s in there.
The first byte of x.ab is a byte bb;. That’s 2 bytes for x so far.
Next, is a A ba;. Let’s see what’s in there.
The first byte of x.ab.ba is a byte aa;. That’s 3 bytes for x so far.
And so on and so forth ad infinitum.
How big is x? The correct answer is of course *** OUT OF CHEESE ERROR ***.

The compiler doesn’t actually do this because it knows it can’t handle this case — so the syntax doesn’t allow circular containment in the first place.


Here’s a diagram of the contents of x in this example:
Diagram


UPDATE

Apparently, I forgot to include a solution here. Now that you understand what the problem is, the solution should be pretty simple. Use pointers. Either use a pointer from A to B and let B include A as it already does, or vice versa, or use two pointers. Then, you won’t have circular inclusion — if B doesn’t include a copy of A but just a pointer to it, that fixes the entire issue here.

  • Remove From My Forums
  • Question

  • Good Morning all,

    I encountered a compiler error c2079 which said «use of undefined class/struc/union name» and am not sure how to solve it. The following is a simplified setup of classes inside my code:

    class a;

    class b {

    int b1;

    public :

    func1();

    }

    b::func1()

    {

    a aclass;

    aclass.a1()     <== this is where error c2079 come from. a1 is a public function of class a

    }

    I search Microsoft C++ compiler error web. It suggests that using pointer to a, instead of instance of a. So I changed

    a aclass      to     a * aclass = NULL;

    and

    aclass.a1()     to     aclass->a1();

    The compiler error changed to c2027 : use of undefined type ‘a’

    Any suggestions? Thanks for your help.

    Tom Lin

Answers

  • I would suggest to split class interface (to be put in .h files) from class implementation (to be put in .cpp file).

    So, you should have 4 files: 

    ClassA.h (header containing interface of class A)

    ClassA.cpp (implementation of class A)

    ClassB.h (header containing interface of class B)

    ClassB.cpp (implementation of class B)

    The implementation of B::func1 method should be put in ClassB.cpp file.

    The implementation of A::a1 method should be put in ClassA.cpp file.

    At the beginning of ClassB.cpp file, you should add a #include «ClassA.h» because you are using class A.

    See if this helps…

    Giovanni

    • Marked as answer by

      Thursday, May 6, 2010 6:41 PM

Цитата
Сообщение от kuroiryuu
Посмотреть сообщение

имеется описание классов в h-файле

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <map>
#include <set>
 
class Node;
class EdgeToNode;
class AdjacencyList;
 
typedef std::set<EdgeToNode> EdgesList;
typedef std::map<size_t, Node> NodesList;
 
class Node
{
public:
    Node(Node & node);
    Node(size_t key, std::wstring name) : key_(key), name_(name) {}
    ~Node();
    void AddDirected(Node node);
    void AddDirected(Node node, double cost);
    void AddDirected(EdgeToNode* edge);
    bool HasNeighbor(size_t key);
 
    inline size_t GetKey() const { return key_; }
    inline std::wstring GetName() const { return name_; }
private:
    size_t key_;
    std::wstring name_;
    AdjacencyList neighbors_; //ОШИБКА C2079!!!
};
 
class EdgeToNode
{
public:
    EdgeToNode(Node neighbor) : neighbor_(neighbor), cost_(1.0) {}
    EdgeToNode(Node neighbor, double cost) : neighbor_(neighbor), cost_(cost) {}
 
    inline double Cost() {return cost_;}
    inline Node Neighbor() const {return neighbor_;} //ОШИБКА C2558!!!
private:
    double cost_;
    Node neighbor_;
};
 
class AdjacencyList
{
public:
    virtual void Add(EdgeToNode e);
    virtual bool Contains(Node node);
    virtual bool Contains(EdgeToNode edge);
    inline EdgesList::iterator GetBeginEdge() {return list_.begin();}
    inline EdgesList::iterator GetEndEdge() {return list_.end();}
private:
    EdgesList list_;
};

при компиляции вылазит две ошибки
error C2558: class ‘Node’ : no copy constructor available or copy constructor is declared ‘explicit’
error C2079: ‘Node::neighbors_’ uses undefined class ‘AdjacencyList’

подскажите как бороться с этими ошибками?

по C2079 пробовал описать переменную Node::neighbors_ как

C++
1
AdjacencyList* neighbors_;

ошибка исчезла, но такое использование указателя не самый лучший способ, хотелось бы узнать как правильно в данной ситуации применить std::auto_prt<AdjacencyList>

У вас возникает ошибка потому, что в классе Node, когда вы определяете член класса AdjacencyList neighbors_;, компилятору не известно определение этого типа, то есть AdjacencyList Вы лишь предварительно объявили этот класс, но не определили, а компилятору, чтобы правильно определить класс Node, нужно знать размер класса AdjacencyList . То есть в этом месте тип AdjacencyList является неполным типом: компилятор не имеет информации о его размере. Когда же вы это поле заменили указателем, то компилятору не нужно само строение класса AdjacencyList , так как размер указателя компилятору в любом случае известен.

Во-втором случае при объявлении функции

C++
1
inline Node Neighbor() const {return neighbor_;}

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

то есть вы передаете не константную ссылку в качестве аргумента. А на временные объекты можно ссылаться только по константной ссылке. То есть компилятор не нашел подходящего конструктора копирования и выдал сообщение об ошибке.

То есть чтобы было понятно, ваша функция

C++
1
inline Node Neighbor() const {return neighbor_;}

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

C#
1
Node(const Node & node);

отсутствует!

  • Remove From My Forums
  • Question

  • Good Morning all,

    I encountered a compiler error c2079 which said «use of undefined class/struc/union name» and am not sure how to solve it. The following is a simplified setup of classes inside my code:

    class a;

    class b {

    int b1;

    public :

    func1();

    }

    b::func1()

    {

    a aclass;

    aclass.a1()     <== this is where error c2079 come from. a1 is a public function of class a

    }

    I search Microsoft C++ compiler error web. It suggests that using pointer to a, instead of instance of a. So I changed

    a aclass      to     a * aclass = NULL;

    and

    aclass.a1()     to     aclass->a1();

    The compiler error changed to c2027 : use of undefined type ‘a’

    Any suggestions? Thanks for your help.

    Tom Lin

Answers

  • I would suggest to split class interface (to be put in .h files) from class implementation (to be put in .cpp file).

    So, you should have 4 files: 

    ClassA.h (header containing interface of class A)

    ClassA.cpp (implementation of class A)

    ClassB.h (header containing interface of class B)

    ClassB.cpp (implementation of class B)

    The implementation of B::func1 method should be put in ClassB.cpp file.

    The implementation of A::a1 method should be put in ClassA.cpp file.

    At the beginning of ClassB.cpp file, you should add a #include «ClassA.h» because you are using class A.

    See if this helps…

    Giovanni

    • Marked as answer by

      Thursday, May 6, 2010 6:41 PM

Понравилась статья? Поделить с друзьями:

Интересное по теме:

  • Ошибка компилятора c2061
  • Ошибка компилятора c2040
  • Ошибка кия р0626
  • Ошибка компилятора 1af8
  • Ошибка кия рио 2192

  • Добавить комментарий

    ;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: