Ошибка c2079 использует не имеющую определения структуру class

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.

loulex

0 / 0 / 0

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

Сообщений: 8

1

Один класс не видит другой

14.04.2018, 10:10. Показов 3142. Ответов 3

Метки нет (Все метки)


Студворк — интернет-сервис помощи студентам

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class apple;
 
class human
{
public:
    int age;
    apple green;
};
 
class apple
{
public:
    string color;
    human man;
 
};

error C2079: «human::green» использует не имеющую определения структуру class «apple»

Как определить нижний класс для верхнего?

Так работает:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class apple;
 
class human
{
public:
    int age;
    //apple green;
};
 
class apple
{
public:
    string color;
    human man;
 
};



0



zss

Модератор

Эксперт С++

13295 / 10431 / 6250

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

Сообщений: 27,866

14.04.2018, 10:30

2

Так получится зацикливание

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

apple green;

В классе human содержится apple

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

human man;

В классе apple содержится human -> в human содержится apple и т.д.
Может имеется ввиду наследование, а не включение:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class apple
{
public:
    string color;
};
class human:public apple
{
public:
    int age;
};
 
 
int main()
{
   humal hh;
   hh.age=18;
   hh.color="green";
}



0



Peoples

Эксперт С++

1623 / 953 / 782

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

Сообщений: 2,449

Записей в блоге: 30

14.04.2018, 10:31

3

Используйте указатель, но у вас явно что-то не так с проектированием. У человека есть яблоко, у яблока есть человек. Наводит на мысль, что так быть не должно

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class apple;
 
class human
{
public:
    int age;
    apple *green;
};
 
class apple
{
public:
    std::string color;
    human man;
 
};



1



0 / 0 / 0

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

Сообщений: 8

14.04.2018, 10:43

 [ТС]

4

Это просто пример



0



Another method is use an intermediate class, plus pointers, its more long, but, it works:

This is header file, ( yes I know, «*.hpp» extension is not standard ):


ForwardClassExample.hpp

class ForwardClass {
public:
  virtual void DoSomething();
};

class ContainerClass {
   ForwardClass* Item;

   /* constructor */ ContainerClass();
   /* destructor */ ~ContainerClass();
};

class RealClass: ForwardClass {
  /* override */ virtual void DoSomething();
};

This is body file:


ForwardClassExample.cpp

/* constructor */ ContainerClass::ContainerClass()
{
  // create reference to forwaded class item
  this.Item = new RealClass();
}

/* destructor */ ContainerClass::~ContainerClass()
{
  // deletereference to forwaded class item
  free this.Item();
}

void ForwardClass::DoSomething()
{
  // ...
}

void RealClass::DoSomething()
{
  // ...
}

Note:

I suggest to get used to apply pointers to variables, instead of direct fields, its may looks more difficult, at start, but, eventually allows to do more stuff.

It also prepare you to use «references» in case, one day you have to work with other programming languages.

Cheers.

  • 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

  • Forum
  • General C++ Programming
  • error C2079: … uses undefined struct .

error C2079: … uses undefined struct …

Long code short:

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
class Creature
{
    Creature(/*...*/) {}
};

struct Enemy : public Creature
{
    Enemy(/*...*/) : Creature(/*...*/)
}

class Combat
{
    Enemy enemy;
    Combat(/*...*/, Enemy enemy) : enemy(enemy) {}
}

class Game
{
    std::vector<Enemy> Enemies;
    Foo()
    {
        Enemy enemy(/*...*/)
        int rand = urand(0, Enemies.size()-1);
        Combat Combat(/*...*/, Enemies[rand])
    }
}

Gives an error:

error C2079: ‘Combat::enemy’ uses undefined struct ‘Enemy’

Where is the problem?

Which line?
You’re missing semicolons after the class declarations.

1
2
Which line?
You're missing semicolons after the class declarations. 

Hmm that was just a mockup. I fixed those semicolons and it seems problem wasnt there. Error was at line 13, Enemy enemy

Edit: I guess i’ll post whole thing when i get back to my computer

Last edited on

Are these in separate files?

Yes

Can you show which classes are in which headers and how each implementation #includes them?

Yeah. I’ve cut some parts a bit but it should do:

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
#ifndef CREATURE_H
#define CREATURE_H

class Creature;

#include "include.h"
#include "spell.h"

class Creature
{
    //blah blah boring stuff here
public:
    Creature() {}
    ~Creature() {}

    Creature(int Atk, int Armor, int Health, int x, int y, int Level, std::string Name)
    {
        //...
    }
    Creature(int Atk, int Armor, int Health, int Level, std::string Name)
    {
        //...
    }
};

#endif 
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
#ifndef ENEMY_H
#define ENEMY_H

struct Enemy;

#include <SFMLGraphics.hpp>
#include "Include.h"
#include "item.h"
#include "player.h"
#include "creature.h"

struct Enemy : public Creature
{
    Enemy(int Atk, int Def, int Health, int x, int y, std::string Alive, std::string Combat, int Level, std::string Name);
    Enemy(int Atk, int Def, int Health, std::string Combat, int Level, std::string Name);
    ~Enemy();

    //...

    struct Loot
    {
        Loot(Item* Item, int Chance) : Item(Item), Chance(Chance) {}
        int Chance;
        Item* Item;
    };
    std::vector<Loot> Loot;
};

#endif 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#ifndef COMBAT_H
#define COMBAT_H

class Combat;

#include "game.h"
#include "enemy.h"
#include "spell.h"
#include "creature.h"

class Combat
{
    sf::RenderWindow &window;
    Player &player;
    Enemy enemy;
    //....
public:
    //...
    Combat(sf::RenderWindow &window, Player &player, Enemy enemy);
    int MainLoop();
};

#endif 
1
2
3
4
5
6
7
//Combat.cpp
#include "combat.h"

Combat::Combat(sf::RenderWindow &window, Player &player, Enemy enemy) : window(window), player(player), enemy(enemy)
{
    TextY = 510;
}
1
2
3
4
//Somewhere in game.cpp Combat object is created
Combat Combat(Window, player, *itr);
Combat.MainLoop();
//itr is std::vector<Enemy>::iterator 

Last edited on

I dont’ see it directly, but I’m willing to bet you have a circular inclusion problem. You appear to be just including all headers willy-nilly. Long story short, combat.h is including enemy.h, which is including some other header that includes enemy.h. The circular inclusion means that your Combat class is being defined before your Enemy class is.

Only include headers you need. See sections 4 and 5 of this article:

http://www.cplusplus.com/forum/articles/10627/#msg49679

Topic archived. No new replies allowed.

Возможно, вам также будет интересно:

  • Ошибка c2065 cout необъявленный идентификатору
  • Ошибка c6000 на kyocera 300i
  • Ошибка c2131 выражение не определяется константой
  • Ошибка c2065 cout необъявленный идентификатор
  • Ошибка c2106 левый операнд должен быть левосторонним значением

  • Понравилась статья? Поделить с друзьями:
    0 0 голоса
    Рейтинг статьи
    Подписаться
    Уведомить о
    guest

    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии