"Field Has Incomplete Type" Error

C - Field has incomplete type

The error means that you try and add a member to the struct of a type that isn't fully defined yet, so the compiler cannot know its size in order to determine the objects layout.

In you particular case, you try and have struct Cat hold a complete object of itself as a member (the mother field). That sort of infinite recursion in type definition is of course impossible.

Nevertheless, structures can contain pointers to other instances of themselves. So if you change your definition as follows, it will be a valid struct:

struct Cat{
char *name;
struct Cat *mother;
struct Cat *children;
};

C++: Field has incomplete type

Incomplete type error means that compiler doesn't see definition of the class, only declaration.
If you create an object or if you pass an object by value then you need to provide a definition of the class to the compiler. You do create objects and pass them around by values hence you need to include definition of relevant classes you pass into cpp files.

But that is not what you really want to do.
Your intention is to employ polymorphism so you need to pass objects by reference or by pointer instead.

Your Animal class should be:

class Animal
{
Fly &myFly;

public:
Animal(Fly &f);
void setFly(Fly &f);
Fly const &getFly();
};

That way you can pass any of Fly, CanFly, or CantFly objects into Animal object.

You also need to reorganise your code. You need to separate class definitions into header files. For example:

//Animal.h
class Fly; <=== Declaration. OK here.
class Animal
{
Fly &myFly;

public:
Animal(Fly &f);
void setFly(Fly &f);
Fly const &getFly();
};

Then you need to include headers into cpp. Example:

#include "Animal.h"
class Dog : public Animal <=== Compiler needs definition of Animal here
{
public:
Dog(Fly f);
};

Note the difference between following definitions:

Fly Animal::getFly()
{
return myFly;
}

Returns a copy of object stored in myFly.

Fly const &Animal::getFly()
{
return myFly;
}

Returns a constant reference to an object myFly

Also, perhaps, you do not need Fly, CanFly, CantFly classes at all. Classes Bird, Dog already "know" if they can or cannot fly. Sure, you are doing an exercise but still Fly, CanFly, etc seem to be redundant and artificial here.

C field has incomplete type

Declarations must be before where they are used, so the two declarations should be swapped.
To allocate player1 and player2, the compiler will require the full declaration of struct player.

Then, you should tell the compiler that struct game will be declared later.
It is enough information to create "pointer to something".

#ifndef SERVER_STRUCTURES_H
#define SERVER_STRUCTURES_H

struct game;

typedef struct player {
int id;
int score;
struct player *player1;
struct game *g ;
} player_t;

typedef struct game {
int id;
struct player player1;
struct player player2;
struct game *next;
} game_t;

#endif

Field has incomplete type in forward declaration

In this case it's simple enough: since Foo only uses a reference to Bar, flipping them around will do the trick:

class Bar; 

class Foo{
public:
void run(int y,Bar& bar);
};

class Bar { ... };

void Foo::run(int y, Bar& bar) {
bar.setx(y);
}

You also need to move the body of Foo::run below, because it's actually using the Bar member function.

C++ error : field has incomplete type - declaring it's own class object

The class isn't fully defined until that closing brace. Before that you can't define objects of the class. A major reason is that the size of the object isn't known yet, so the compiler doesn't know how much memory to allocate for the member variables.

When you use pointers or references to the class, the compiler will know how much memory a pointer or reference takes up, as it's unrelated to the size of the actual class.

Field has incomplete type error

typedef struct tcpsock tcpsock_t; defines tcpsock_t as a struct tcpsock. Hence, your struct definition must look like this:

struct conn{
tcpsock_t socket;
long last_active;
};

A class has incomplete type

The problem is that when you wrote:

void A_lookup(B b){ //this statement needs B to be a complete type
cout << b.b_i <<endl; //this also needs B to be a complete type
}

In the above member function definition, the parameter b is of type B. And for B b to work, B must be a complete type. Since you have only declared class B and not defined it, you get the mentioned error. Moreover, the expression b.b_i needs B to be a complete type as well.

Solution

You can solve this by declaring the member function A_lookup inside the class A and then defining it later when B is a complete type as shown below:

#include <iostream>
class B;
class A{
public:
int a_i=10;

//only a declaration here
void A_lookup(B b);
};
class B{
public:
int b_i=20;
void B_lookup(A a){
std::cout << a.a_i <<std::endl;
}
};
//this is a definition. At this point B is a complete type
void A::A_lookup(B b)
{
std::cout << b.b_i <<std::endl;
}
int main(void){
A a;
B b;
a.A_lookup(b);
}

Demo

Solution 2

Note that you can also make the parameters a and b to be a reference to const A or reference to const B respectively as shown below. Doing so has some advantages like now the parameter a and b need not be complete type. But still expression a.a_i and b.b_i will need A and B respectively to be complete type. Also, now the argument will not be copied since now they will be passed by reference instead of by value.

#include <iostream>
class B;
class A{
public:
int a_i=10;
void A_lookup(const B& b); //HERE ALSO void A_lookup(const B& b){ std::cout << b.b_i <<std::endl;} WILL NOT WORK

};
class B{
public:
int b_i=20;
void B_lookup(const A& a){
std::cout << a.a_i <<std::endl;
}
};

void A::A_lookup(const B& b)
{
std::cout << b.b_i <<std::endl;
}
int main(void){
A a;
B b;
a.A_lookup(b);
}

Demo


Also refer to Why should I not #include <bits/stdc++.h>?.



Related Topics



Leave a reply



Submit