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
Why Use !! When Converting Int to Bool
How to Build Boost Version 1.58.0 Using Visual Studio 2015 (Enterprise)
What Is the Comdat Section Used For
Convert Eigen Matrix to C Array
Advantages of Classes with Only Static Methods in C++
How to Rotate a N X N Matrix by 90 Degrees
Std::Forward_List and Std::Forward_List::Push_Back
Comparing Std::Functions for Equality
How to Avoid Entering Library's Source Files While Debugging in Qt Creator with Gdb
Why Can't I Initialize a Reference in an Initializer List with Uniform Initialization
Lambda Functions as Base Classes
When Virtual Inheritance Is a Good Design
Do I Have to Bind a Udp Socket in My Client Program to Receive Data? (I Always Get Wsaeinval)
Do I Have to Use Atomic<Bool> for "Exit" Bool Variable
Do Static Members of a Class Occupy Memory If No Object of That Class Is Created