Another invlid use of incomplete type - c++

I have been looking for a solution to this for a few days now. I will spare the details and just display the code:
#include "Mesh/GEdge.h"
//class GEdge;
class GEdgeSigned
{
public:
int _sign;
GEdge *ge;
GEdgeSigned(int i, GEdge *g) : _sign(i), ge(g) {}
GVertex *getBeginVertex() const
{
return (_sign == 1) ? ge->getBeginVertex() : ge->getEndVertex();// Error here
}
GVertex *getEndVertex() const
{
return (_sign != 1) ? ge->getBeginVertex() : ge->getEndVertex(); // Error Here
}
void print() const;
int getSign() const { return _sign; }
};
So basically, I have the invalid error at the locations marked. I clearly have the #include header at top and when you look into the header (the GEdge.h) there is no circular reference.
However, if you open a few more header files that are included in the GEdge.h file, you will end up with a circular reference.
So my question is this, if Edge.h is included 4 files deep, would this still be a circular reference causing the error?
If not, what are some other common issues that cause the invalid type error?

Related

What is causing these 'unexpected tokens' errors after constructor?

I am working on a circuit simulator/pathfinding system, but I keep getting these weird compilation errors. I am not yet that experienced with OO C++ to figure it out myself...
Object Tree
The objects in my project are implemented in this way:
Object
Component
Wire
Switch
Ciruit
My Object class is the base class for everything in my project, this is great for debugging by giving everything a name and an id.
I required that every component needs a Circuit to with (see it as a parent for components). I implemented this by creating a constructor in the Component class that requires a reference to a Circuit object.
At first, everything worked and compiled fine, but when I introduced the Circuit class and when I added a constructor in Component with a Circuit reference parameter, everything went wrong...
Compilation errors
Now I keep getting these seemingly random syntax and missing tokens errors. (Intellisense does not mark them?)
The first four errors that pop up are:
C2238: unexpected token(s) preceding ';'.
At line 10 of Component.hpp. And at line 12 in file Circuit.hpp.
Both just after the constructor definition. (See in code below)
The next four errors point tot the same locations, but it notes:
C2143: syntax error: missing ';' before '*'.
Then, 30 more errors follow, but I think they are a result of these errors, to be sure, here they are:
(Lol, cannot embed image, caused by not having enough reputation, so a link instead...)
Click here for errors
What I tried
I tried the following:
Using a reference instead of pointer. (changed Circuit* c to Circuit& c)
Removing the name string concationation thing in constructor initializer list. (changed ... : Object(name + "blah") to ... : Object(name))
Rewriting the whole Visual Studio project to a new Visual Studio project.
Placing the constructor initializer list in the header file.
Lots of googling... and not lots of solving...
How to fix?
This frustrating problem is stopping me from working further on this project, what is causing it and how do I fix it? I would be pretty happy to know.
Object.hpp
#pragma once
#include <string>
using std::string;
class Object
{
public:
Object();
Object(string name);
string name;
const int id;
virtual string toString();
private:
static int currentId;
};
Object.cpp
#include "Object.hpp"
int Object::currentId = 0;
Object::Object() : id(++Object::currentId), name("Object")
{ }
Object::Object(string name) : id(++Object::currentId), name(name)
{ }
string Object::toString()
{
return name + "#" + std::to_string(id);
}
Component.hpp
#pragma once
#include "Object.hpp"
#include "Circuit.hpp"
class Component : public Object
{
public:
Component(std::string name, Circuit* container);
Circuit *container; // <- Error points to the beginning of this line
};
Component.cpp
#include "Component.hpp"
Component::Component(string name, Circuit* container) : Object(name), container(container)
{ }
Switch.hpp
#pragma once
#include "Component.hpp"
#include "Wire.hpp"
class Switch : public Component
{
public:
Switch(string name, Circuit* container, Wire& wire1, Wire& wire2);
Wire* wire1;
Wire* wire2;
void setEnabled(bool enabled);
bool getEnabled();
private:
bool enabled;
};
Switch.cpp
Switch::Switch(string name, Circuit* container, Wire& wire1, Wire& wire2) : Component(name + "-Switch", container), wire1(&wire1), wire2(&wire2), enabled(false)
{ }
...
Circuit.hpp
#pragma once
#include "Object.hpp"
#include "Wire.hpp"
class Circuit : public Object
{
public:
Circuit(std::string name);
Wire* powerWire; // <- Error points to the beginning of this line
bool isPowered(Wire& wire);
bool getActive();
void setActive(bool active);
private:
bool active;
};
Circuit.cpp
#include "Circuit.hpp"
#include "Util.hpp"
Circuit::Circuit(string name) : Object(name + "-Circuit")
{
active = false;
powerWire = new Wire(name + "-PowerWire", this);
}
...
You haven't shown Wire.hpp, but my guess is that it includes Component.hpp, which gives you a cycle in header inclusion (because Component.hpp includes Circuit.hpp, and Circuit.hpp includes Wire.hpp).
You will have to replace some of these inclusions with forward declarations to break the cycle.

'Render': 'class' type redefinition (C2011)

There are a lot of similar questions on Stack Overflow, regarding this topic.
I am creating a project with multiple files (.cpp and .h). I am getting the error:
C2011: 'Render': 'class' type redefinition
I have read about it. Some people are saying use guards, so I am using #pragma once on all header files. Some people say the header is being included multiple times, but the guards will prevent that. So what am I doing wrong?
Code:
Cubes.h
#pragma once
char orientation(int sides, int hV);
std::vector<char> visOrd(std::string *xOrd, int *pov, int ord);
std::vector<int> convertColour(std::vector<std::string> rlBoxCol);
std::tuple<std::vector<int>, std::vector<std::string>> organiseLayers(std::vector<int> boxCoords, std::vector<std::string> rlBoxCol, std::vector<float> rot);
class Render
{
private:
std::vector<float> rot;
std::vector<int> boxCoords;
std::vector<std::string> rlBoxCol;
int gridSize;
int cubeSize;
std::vector<int> offset;
public:
Render();
void setRotation(std::vector<float> setRot);
std::vector<float> getRotation();
void setCoordinates(std::vector<int> setBoxCoords);
std::vector<int> getCoordinates();
void setColours(std::vector<std::string> setRlBoxCol);
std::vector<std::string> getColours();
void setSizeOfGrid(int setGridSize);
int getSizeOfGrid();
void setSizeOfCubes(int setCubeSize);
int getSizeOfCubes();
void setOffset(std::vector<int> setOffset);
std::vector<int> getOffset();
void display();
};
Cubes.cpp
#include "Cubes.h"
#include "Global.h"
char orientation(int sides, int hV)
{
// Code
}
std::vector<char> visOrd(std::string *xOrd, int *pov, int ord)
{
// Code
}
std::vector<int> convertColour(std::vector<std::string> rlBoxCol)
{
// Code
}
std::tuple<std::vector<int>, std::vector<std::string>> organiseLayers(std::vector<int> boxCoords, std::vector<std::string> rlBoxCol, std::vector<float> rot)
{
// Code
}
Render::Render()
{
this->rot;
this->boxCoords;
this->rlBoxCol;
this->gridSize;
this->cubeSize;
this->offset;
}
void Render::setRotation(std::vector<float> setRot)
{ // Set rotation
rot = setRot;
}
std::vector<float> Render::getRotation()
{ // Get rotation
return rot;
}
void Render::setCoordinates(std::vector<int> setBoxCoords)
{
boxCoords = setBoxCoords;
}
std::vector<int> Render::getCoordinates()
{
return boxCoords;
}
void Render::setColours(std::vector<std::string> setRlBoxCol)
{
rlBoxCol = setRlBoxCol;
}
std::vector<std::string> Render::getColours()
{
return rlBoxCol;
}
void Render::setSizeOfGrid(int setGridSize)
{
gridSize = setGridSize;
}
int Render::getSizeOfGrid()
{
return gridSize;
}
void Render::setSizeOfCubes(int setCubeSize)
{
cubeSize = setCubeSize;
}
int Render::getSizeOfCubes()
{
return cubeSize;
}
void Render::setOffset(std::vector<int> setOffset)
{
offset = setOffset;
}
std::vector<int> Render::getOffset()
{
return offset;
}
void Render::display()
{
// Drawing code
}
EDIT:
I have now changed the code in ways you said. Now I am getting errors LNK2005 and LNK1169. What's gone wrong now?
EDIT 2: (Errors)
LNK2005
"class sf::RenderWindow Window" (?Window##3VRenderWindow#sf##A) already defined in Cubes.obj
C:\Users\George\Documents\C++\Projects\Don't fall\Don't fall\main.obj 1
.
LNK2005
"class std::basic_string,class std::allocator > status" (?status##3V?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std##A) already defined in Cubes.obj
C:\Users\George\Documents\C++\Projects\Don't fall\Don't fall\main.obj 1
.
LNK1169
one or more multiply defined symbols found
C:\Users\George\Documents\C++\Projects\Don't fall\Debug\Don't fall.exe 1
Global.h:
#pragma once
#include <SFML\Graphics.hpp>
// This is where all my global variables will be
extern sf::RenderWindow Window(sf::VideoMode(500, 500), "Maximize window to play the game");
extern std::string status = "NULL";
Your Cubes.cpp does redefine the class Render. In general the .h file has the class prototype and the .cpp defines the methods.
Try adding this to the top of the Cubes.cpp:
#include "Cubes.h"
removing this from the top of Cubes.cpp:
class Render
{
private:
std::vector<float> rot;
std::vector<int> boxCoords;
std::vector<std::string> rlBoxCol;
int gridSize;
int cubeSize;
std::vector<int> offset;
public:
and removing this from the bottom:
};
This is not how you provide the implementation of a class in C++. The keyword class defines the class, which is what you have in your header (.h file). In the .cpp file you wish to implement the methods which you defined in your header file, so you should not redefine the entire class. Rather, you need to provide implementations for the methods (member functions) of the class, like so:
void Render::setRotation(std::vector<float> setRot)
{ // Set rotation
rot = setRot;
}
std::vector<float> Render::getRotation()
{ // Get rotation
return rot;
}
Notice the prefix Render::? This is how you indicate that you are providing an implementation for the function setRotation of the class Render. Just add the function implementation like this in your cpp, do not nest them within a class, do not include any fields (the member fields have already been defined in the header, they are done).
Update:
OK, so according to the updated answer your linker error refers to the instances sf::RenderWindow Window and std::string status; this error occurs when linking main.obj (from main.cpp?) with Cubes.obj. The error is telling you that both main.obj and Cubes.obj define these variables.
I recommend that you read about "Compilation Units" in C++ and difference between declaration and definition of a symbol; but to give a very brief summary:
Essentially, the compiler runs on a single "compilation unit"; you can think of it as a single file. What the #include-statement does is basically copy/paste the content of the included file into the compilation unit. So when you compile Cubes.cpp, it will go through all of the nested includes until it has generated one huge cpp-file with everything included. Then it will build this into an .obj file. Then you do the same thing with main.cpp, and any other .cpp files you might have. Finally, the linker will attempt to link these object files together to produce the final result.
Now, if the linker finds duplicate definitions when linking two objects you will get an error. So you cannot have two global variables with the same name! If both Cubes.cpp and main.cpp include global.h, then both compilation units contain global variable definitions Window and status. This is causing your linker error.
This is why you put a declaration in the header (since it is included in multiple compilation units), and the definition in the source file (typically not included elsewhere). You build the source file to produce the only object file containing the definition; all other object files only reference the declaration. The linker can then link those references to the definition found in one the object files.
So you want to declare the variables in the header, and move the definition somewhere else. For instance, to main.cpp; but that depends entirely on the rest of your application and what you are trying to achieve. Outside the scope of the question.

Why does this not marking an operator overload as inline cause a duplicate definition error?

After creating the following class, compilation fails with many "duplicate symbol" errors. The actual error is not very descriptive :
"duplicate symbol __Zeq.... in :
/Users/myusername/Library/Developer/Xcode/DerivedData/MyProject-asdfasfasdf..../Build/Intermediates/MyProject.build/Debug-iphonesimulator/MyTarget.build/Objects-normal/i386/MyClass.o
"
The above same message appears for many different classes, and appears at the end of compilation, so I don't know what the problem is.
I have checked the following:
Classes that use this, include the Listening.hpp file.
The only definition for this class, is in this file.
What can the problem be ?
#ifndef Listening_hpp
#define Listening_hpp
#include <stdio.h>
#include "EAction.hpp"
class Listening{
private:
int _emitterId;
int _listenerId;
std::string _eventName;
EAction* _actionToTake; //not owned.
protected:
public:
Listening(int emitterId,int listenerId,std::string eventName,EAction* actionToTake) : _emitterId(emitterId),_listenerId(listenerId),_eventName(eventName){
_actionToTake = actionToTake;
}
int getEmitterId()const{
return _emitterId;
}
int getListenerId()const{
return _listenerId;
}
std::string getEventName()const{
return _eventName;
}
EAction* getAction()const{
return _actionToTake;
}
};
bool operator==(const Listening &first,const Listening &other)
{
bool result = false;
if(first.getEmitterId() == other.getEmitterId()){
if(first.getListenerId() == other.getListenerId()){
if(first.getEventName() == other.getEventName()){
if (first.getAction() == other.getAction()) {
result = true;
}
}
}
}
return result;
}
bool operator!=(const Listening &first,const Listening &other)
{
bool result = !(first == other);
return result;
}
#endif /* Listening_hpp */
EAction.hpp
#ifndef EAction_hpp
#define EAction_hpp
#include <stdio.h>
class EAction{
private:
protected:
public:
virtual std::vector<std::size_t> seedList() = 0;
};
#endif /* EAction_hpp */
EDIT: Edited the title - I think this may help people who have a duplicate definition error for other reasons ignore this answer.
The free functions in the header file must either be marked inline, or changed to have only declarations in the header:
inline bool operator==(const Listening &first,const Listening &other)
{
and similarly for operator!=.
The original problem is that any unit including this header file will have its object file contain a copy of the operator==. Then the linker sees this and doesn't know which one is meant to be the right one. The inline can be thought of as a linker directive to say "All these functions are the same, just pick one". Link to more detailed answers.
The same problem didn't happen with the class member function bodies because such bodies written inside the class definition are implicitly inline.
Historical note: Originally, inline was primarily an optimization directive. However, nowdays compilers are smart enough to make optimization decisions on their own; so the primary use of inline now is what was once the secondary effect: to avoid multiple definition errors when having a function in a header.
BTW, you can write return bla; , instead of assigning bla to a bool variable and so on.

"Expected Class name" Error for Inheritance

Problem
Currently designing a GUI game, and I've finished the basic OOP aspects of the game(along with 90% of all non-abstract classes). However, I tried extending a class called Protester to this class which caused the error at line 5 here:
#ifndef HardcoreProtester_h
#define HardcoreProtester_h
#include "Protester.h"
class HardcoreProtester : public Protester{
public:
HardcoreProtester(StudentWorld* w, int x, int y) : Protester(w, x, y, IID_HARD_CORE_PROTESTER, 20){};
private:
};
#endif /* HardcoreProtester_h */
when extending from this
#ifndef Protester_h
#define Protester_h
#include "Actor.h"
#include "StudentWorld.h"
class Protester : public Human{
static const int INIT_PERP_TICK = 200;
static const int DAMAGE = 20;
static const int SHOUT_WAIT = 25;
static const int MIN_STEP = 8;
static const int MAX_STEP = 60;
static const int EXIT_X = 60;
static const int EXIT_Y = 60;
public:
static const int INIT_HITPOINTS = 5;
Protester(StudentWorld* w, int startX, int startY, int ID, int hp);
virtual ~Protester();
virtual void doSomething();
Direction pickRandomDirection();
virtual bool changeState(Direction dir);
virtual bool isDead() const{
return Human::isDead() && getX() == 60 && getY() == 60;
}
virtual bool isDeadState() const{
return Human::isDead();
}
virtual void consume();
virtual void setDead();
virtual bool moveDelta(StudentWorld* world, Direction dir, int& xdir, int& ydir, int steps = 1);
int determineRandomSteps();
bool canTurn(Actor::Direction dir);
Actor::Direction randTurn(Actor::Direction dir);
Actor::Direction oppositeDir(Actor::Direction dir);
Actor::Direction numToDir(int num);
private:
int step;
int restTick;
int shoutTick;
int perpTick;
};
#endif /* Protester_h */
I've looked on stack overflow for answers to why the error persists, and I've tried to break a nonexistent circular dependency (as you can see Protester does not even include HardcoreProtester). I tried to break any circular dependency by adding a
class Protester;
above the definition of HardcoreProtester.
However, this gives me the error:
Type 'Protester' is not a direct or virtual base of 'HardcoreProtester'
and
Base class has incomplete type
I also made sure the base class is not abstract(I was able to initialize it without any errors).
If this isn't enough information, here's the github for the project:
https://github.com/OneRaynyDay/FrackMan
I apologize for any ambiguity in my question - I just simply have no idea where the error could be(hence an attempt for MCVE with github link). Thanks in advance!
EDIT: Also, using XCode to make this project. By this point into debugging I'm starting to suspect XCode of being the culprit.
In addition, just to be extra helpful and verifiable, here's a picture of the error diagnosis from XCode:
No, XCode is not the culprit. It's not XCode's fault that you have circular header dependencies.
According to the compiler dump you posted, it appears that your StudentWorld.h header file has a #include of HardProtester.h.
This is a case of classical circular header dependencies.
First, you are including Protester.h.
Before Protester.h even gets to its definition of the Protester class, it has an #include of StudentWorld.h.
StudentWorld.h must have an #include of HardProtester.h, according to your compiler's error diagnostics.
Now, your HardProtester.h has it's own include of Protester.h. But, because its ifndef/define guard has already been set, in the first include of Protester.h, the second #include of this header file becomes empty text.
And now, upon returning to HardProtester.h, you attempt to declare it's class.
Now, if you have been paying attention carefully, you should've figured out that the Protester class has not yet been declared, yet this header file attempts to declare its subclass.
There's your problem. You need to completely refactor how your header files depend on each other, to eliminate this circular dependency. Merely sticking a "class Protester" in HardProtester.h is insufficient. The entire class must be defined, not just declared, before you can declare any subclasses.
You have a circular dependency between Protester.h and StudentWorld.h
Try fixing that and see if it helps.

c++ "Incomplete type not allowed" error accessing class reference information (Circular dependency with forward declaration)

Had some issues in my code recently surrounding what I now know of as a Circular dependency. In short there are two classes, Player and Ball, which both need to use information from the other. Both at some point in the code will be passed a reference of the other (from another class that will include both .h files).
After reading up on it, I removed the #include.h files from each one and went with forward declaration. This solved the issue of being able to declare the classes in eachother, but I'm now left with an "Incomplete type error" when trying to access a passed reference to the object. There seem to be a few similar examples around, though often mixed with more complex code and hard to narrow down to the basics.
I've rewritten the code in it's simplest form (a skeleton essentially).
Ball.h:
class Player;
class Ball {
public:
Player& PlayerB;
float ballPosX = 800;
private:
};
Player.h:
class Ball;
class Player {
public:
void doSomething(Ball& ball);
private:
};
Player.cpp:
#include "Player.h"
void Player::doSomething(Ball& ball) {
ball.ballPosX += 10; // incomplete type error occurs here.
}
Any help understanding why this is the case would be greatly appreciated :)
If you will place your definitions in this order then the code will be compiled
class Ball;
class Player {
public:
void doSomething(Ball& ball);
private:
};
class Ball {
public:
Player& PlayerB;
float ballPosX = 800;
private:
};
void Player::doSomething(Ball& ball) {
ball.ballPosX += 10; // incomplete type error occurs here.
}
int main()
{
}
The definition of function doSomething requires the complete definition of class Ball because it access its data member.
In your code example module Player.cpp has no access to the definition of class Ball so the compiler issues an error.
Player.cpp require the definition of Ball class. So simply add #include "Ball.h"
Player.cpp:
#include "Player.h"
#include "Ball.h"
void Player::doSomething(Ball& ball) {
ball.ballPosX += 10; // incomplete type error occurs here.
}
Here is what I had and what caused my "incomplete type error":
#include "X.h" // another already declared class
class Big {...} // full declaration of class A
class Small : Big {
Small() {}
Small(X); // line 6
}
//.... all other stuff
What I did in the file "Big.cpp", where I declared the A2's constructor with X as a parameter is..
Big.cpp
Small::Big(X my_x) { // line 9 <--- LOOK at this !
}
I wrote "Small::Big" instead of "Small::Small", what a dumb mistake..
I received the error "incomplete type is now allowed" for the class X all the time (in lines 6 and 9), which made a total confusion..
Anyways, that is where a mistake can happen, and the main reason is that I was tired when I wrote it and I needed 2 hours of exploring and rewriting the code to reveal it.
In my case it was because a typo.
I had something like
struct SomethingStrcut { /* stuff */ };
typedef struct SomethingStruct smth;
Notice how the name of the structure is not the same one as the type definition.
I misspelled struct to strcut.
Look into your code and see wether you have some typos.