Unknown override specifier + missing type specifier - c++

I'm using Visual Studio 2015 Update 2.
I have two headers called Error.h and Game.h.
Error.h:
#ifndef _Error_H
#define _Error_H
#include "Main.h"
#include "Core.h"
#include <Log.h>
#include <CWindows.h>
// ErrorIDs
enum
{
ErrUnknownID = 0,
blah,
blah2,
blah3
};
struct ErrInfo
{
unsigned int eiID;
String strCaption; // String is another class which implemented from std::string which works fine!
String strText;
bool bFixable = false;
};
// Static errors
extern ErrInfo WinNotSupported;
// blah blah
class Error
{
public:
void Initialize();
bool ShowError(ErrInfo ErrorInfo);
BOOL FixError(unsigned int uiErrorID);
// -----------------------------------------
// --------------- Singleton ---------------
// -----------------------------------------
public:
static Error& Instance()
{
static Error instance;
return instance;
}
static Error *InstancePtr()
{
return &Instance();
}
private:
Error()
{
}
public:
Error(Error const&) = delete;
void operator=(Error const&) = delete;
};
#endif // !_Error_H
And Game.h:
#ifndef _Game_H
#define _Game_H
#include "Main.h"
#include "Error.h"
#include "Core.h"
#include <CWindows.h>
#include <AFile.h>
struct missingfileSt
{
String strFileURL;
String strDLFileName;
String strFileName;
String strChecksum;
long long llSize;
ErrInfo errError; // Many errors here <-
};
struct deletablefileSt
{
String strFileName;
ErrInfo errError; // Many errors here too
};
#define siMissingFiles 7
#define siDeletableFiles 5
class Game
{
public:
void ValidateFiles();
DWORD dwGamePID;
missingfileSt mfMissingFiles[siMissingFiles];
deletablefileSt dfDeletableFiles[siDeletableFiles];
// -----------------------------------------
// --------------- Singleton ---------------
// -----------------------------------------
public:
static Game& Instance()
{
static Game instance;
return instance;
}
static Game *InstancePtr()
{
return &Instance();
}
private:
Game()
{
dwGamePID = 0;
}
public:
Game(Game const&) = delete;
void operator=(Game const&) = delete;
};
#endif // !_Game_H
Now, when I compile I get many errors from Game.h and all of them are:
Error C3646 'errError': unknown override specifier
Error C4430 missing type specifier - int assumed. Note: C++ does not support default-int
I got really confused, why errors!?
Also I must say, in header Core.h it will include Error.h again but it mustn't be problem!

An old question already but a useful answer is missing for all C++ newbies or those who are forced to understand (very) bad C++ compiler messages.
If you get "missing type specifier", "unknown override", "undefined type/class", "syntax error: (" (for a beginning function parameter list) although you included the proper header file then it indicates that there is some circular reference in your include-hierarchy. This is also true if you have a forward declaration and the type is still "unknown".
The only solution with the old include-system in C++ is to avoid circular references between #includes. It's achieved by moving #includes from a header file A.h to the A.cpp and by forward declaring the types (or methods) in A.h. If you don't move the #include to A.cpp it still can fail despite forward declaration.
Let A.h be a circular include in B.h because B.h would already be included by A.h. Instead of
#include "A.h"
class B {
A a;
}
you can write
class A;
class B {
A a;
}
and include A.h in your CPP file(s).
You can avoid the need for method forward declarations if you only define methods in CPP files.

I just moved ErrInfo struct to another header with the same include guard and it compiled and worked without problem, I think it's compiler failure, if it isn't please explain.

Related

C++ Can a class pass itself by reference?

Trying to pass a parent class object to a child class object so that the child class object has control over the parent class object's methods.
This is however resulting in header related issues.
I've tried forward declaring one of the classes but it seems whatever class is declared first always has trouble reading from the class declared below.
Both errors refer to Device' constructor where try to call dm's hello world method, they are:
Use of undefined type 'DeviceManager'
Left of '->HelloWorld' must point to class/struct/union/generic type
...
//main.cpp
#include "parent.h"
void main()
{
cout << "Created DeviceManager\n";
DeviceManager* deviceManager = 0;
deviceManager = new DeviceManager;
cout << "Giving DeviceManager a device\n";
deviceManager->p = new Device(deviceManager);
cout << "Giving Device a reference to DevicenManager\n";
deviceManager->Share();
}
...
class DeviceManager;
class Device
{
public:
Device(DeviceManager* manager)
{
dm = 0;
this->dm = manager;
this->dm->HelloWorld();
}
DeviceManager* dm;
};
//device manager
class DeviceManager
{
public:
DeviceManager()
{
p = 0;
}
void HelloWorld()
{
//if this calls we know the child has control over the parent.
cout << "Hello World";
}
Device* p;
};
Yes.
To solve circular dependencies with class member and function declarations, you can forward-declare a class:
class A;
class B {
A *a;
};
class A {
B *b;
};
To define class member functions that access members of the other class, you must define the function after the other class has been defined:
class B;
class A {
public:
void f(B &arg);
};
class B {
public:
void g(A &arg);
};
void A::f(B &arg) {
arg.g(*this);
}
void B::g(A &arg) {
arg.f(*this);
}
Usually, in a C++ project, you wouldn't even encounter this problem: You would put function definitions, i.e. implementations, into .cpp files, while putting the class definitions into header files. Class forward declarations, if neccesary, could be put into their own header files that are included by all headers that need them.
A full example of how you would split the above code into multiple files:
a.cpp
#include "a.h"
#include "b.h"
void A::f(B &arg) {
arg.g(*this);
}
b.cpp
#include "b.h"
#include "a.h"
void B::g(A &arg) {
arg.f(*this);
}
a.h
#ifndef _A_H_
#define _A_H_
#include "forward_declarations.h"
class A {
public:
void f(B &arg);
};
#endif //_A_H_
b.h
#ifndef _B_H_
#define _B_H_
#include "forward_declarations.h"
class B {
public:
void g(A &arg);
};
#endif //_B_H_
forward_declarations.h
#ifndef _FORWARD_DECLARATIONS_H_
#define _FORWARD_DECLARATIONS_H_
class A;
class B;
#endif //_FORWARD_DECLARATIONS_H_
As a general rule of thumb, if you need to forward-declare a class, you might have misdesigned something and should think about whether there is a better way (but there also are perfectly valid use cases that require class forward declarations).
If you don't understand my #ifndef, #define and #endif preprocessor lines: These are header guards, and should be used with all files that are included somewhere else, exception you know precisely what you're doing. Believe me. You'll regret ommiting one.
If your problem is cyclic dependancy, like this:
// DeviceManager.h
#include "device.h"
class DeviceManager
{
DeviceManager(Device& device) {}
};
// Device.h
#include "DeviceManager.h"
class Device
{
Device(DeviceManager& manager) {}
};
You can solve the problem be forward declaring one of the classes, and passing the object by pointer.
// Device.h
//#include "DeviceManager.h"
class DeviceManager;
class Device
{
Device(DeviceManager* manager) {}
};

Why do I get incomplete type when using forward declaration instead of #include?

Here I have state_machine.h:
#ifndef STATE_MACHINE_H
#define STATE_MACHINE_H
// state machine classes
//#include "state_t.h"
class state_t;
class state_machine
{
public:
state_machine();
void change_state(state_t *newState);
void process_state(int data);
private:
state_t *_state;
};
#endif // STATE_MACHINE_H
And here is state_t.h:
#ifndef STATE_T_H
#define STATE_T_H
#include <QByteArray>
#include <QDebug>
//#include "state_machine.h"
class state_machine;
class state_t
{
public:
state_t(QByteArray stateName);
virtual ~state_t();
virtual void processState(state_machine *sm, int input) = 0;
void defaultUnknownEventHandler(int event);
QByteArray name;
};
#endif // STATE_T_H
Then some state classes, which are all the same more or less, I'll just list one:
teststate1.h:
#ifndef TESTSTATE1_H
#define TESTSTATE1_H
#include "state_t.h"
class testState1 : public state_t
{
public:
testState1();
void processState(state_machine *sm, int event);
};
#endif // TESTSTATE1_H
teststate.cpp:
#include "teststate1.h"
#include "teststate2.h"
testState1::testState1() :
state_t("state1")
{
}
void testState1::processState(state_machine *sm, int event)
{
qDebug() << name << ": event" << event;
switch (event)
{
case 2:
{
// error: invalid use of incomplete type 'class state_machine'
sm->change_state(new testState2());
break;
}
default:
{
defaultUnknownEventHandler(event);
break;
}
}
}
The problem:
I am trying to tidy up my code and use the minimal amount of header inclusion (especially in header files) by using forward declarations. You can see in the state_machine class header I have commented out #include "state_t.h" and replaced it with a forward declaration class state_t;. This worked and my code compiled and ran.
Then, in state.h I replaced #include "state_machine.h" with a forward declaration class state_machine; (you can see where I commented it out).
But now I get the error error: invalid use of incomplete type 'class state_machine' which I have commented in testState1.cpp code. But I am not sure why. Why is state_machine an incomplete type?
teststate.cpp needs the definition of state_machine; so include state_machine.h there.
"Incomplete" means that the compiler has only seen a declaration, class state_machine;, not a full definition. You can do various things with an incomplete type, such as declaring pointers or references. But you can't call member functions (as you do here), or more generally do anything that requires knowledge of the class members, without the full definition.

C++ Method declaration using another class

I'm starting to learn C++ (coming from Java), so bear with me.
I can't seem to get my method declaration to accept a class I've made.
'Context' has not been declared
I think I'm not understanding a fundamental concept, but I don't know what.
Expression.h
#include "Context.h"
class Expression {
public:
void interpret(Context *); // This line has the error
Expression();
virtual ~Expression();
};
Context.h
#include <stack>
#include <vector>
#include "Expression.h"
class Context {
private:
std::stack<Expression*,std::vector<Expression*> > theStack;
public:
Context();
virtual ~Context();
};
You have to forward declare Expression in Context or vice versa (or both), otherwise you have a cyclic dependency. For example,
Expression.h:
class Context; // no include, we only have Context*.
class Expression {
public:
void interpret(Context *); // This line has the error
Expression();
virtual ~Expression();
};
Context.h:
#include <stack>
#include <vector>
class Expression; // No include, we only have Expression*
class Context {
private:
std::stack<Expression*,std::vector<Expression*> > theStack;
public:
Context();
virtual ~Context();
};
You can perform the forward declarations because the full definition of the classes isn't needed, since you are only referring to pointers to the other class in each case. It is likely that you will need the includes in the implementation files (that is, #include "Context.h" in Expression.cpp and #include Expression.h in Context.cpp).
Finally, remember to put include guards in your header files.
In C++, class definitions always have to end with a semi-colon ;
so example:
class foo {};
Java and C# doesn't require that, so I can see your confusion.
Also it looks like both your header files include each other. Thus it's kind of like a snake eating it's tail: Where does it start? Thus in your Expression.h you can replace the 'include' with a forward declaration instead:
class Context;
class Expression {
public:
void interpret(Context *); // This line has the error
Expression();
virtual ~Expression();
}
And last but not least, you should put a compiler guard to prevent the header from getting included more than once into a .cpp file. You can put a #pragma once in the top of the header file. That is useful if you are using visual studio and the microsoft compiler. I don't know if GCC supports it or not. Or you can wrap your header file like this:
#ifndef EXPRESSION_H_
#define EXPRESSION_H_
class Context;
class Expression {
public:
void interpret(Context *); // This line has the error
Expression();
virtual ~Expression();
}
#endif
you might need to forward declare the classes Context and Expression in the header files before the #include
e.g.
#include <stack>
#include <vector>
// forward declaration
class Context;
class Expression;
#include "Expression.h"
class Context {
private:
std::stack<Expression*,std::vector<Expression*> > theStack;
public:
Context();
virtual ~Context();
}

Inaccessible object when compiling code

I want to compile the Rigi source code but I get some error while compiling:
adt/object.h: At global scope:
adt/object.h:35:18: error: ‘class RigiObject RigiObject::RigiObject’ is inaccessible
adt/chararray.h:51:13: error: within this context
make: *** [cl_arcflags.o] Error 1
Here our two files.
object.h:
#ifndef OBJECTH
#define OBJECTH 1
#include <stdio.h>
#ifndef STREAM_H
#include <iostream>
#endif
#ifndef __STRING_H
#include <string.h>
#endif
#ifndef __STDLIB_H
#include <stdlib.h>
#endif
#ifndef _CCHEADER_H_
#include "CCheader.h"
#endif
extern char* indent_line(int);
class RigiObject;
typedef RigiObject* ObjectPtr;
#define Oberr(a) fprintf(stderr,"ERROR :: Generic Object Routine Called :: %s\n","a");
class RigiObject {
public:
RigiObject() {/*Oberr(RigiObject)*/;}
~RigiObject() {/*Oberr(~RigiObject)*/;}
// Routines that are really described by the Derived Classes
virtual int Printout(int) const
{Oberr(printout); return (int) 0;}
virtual unsigned int Hash() const
{Oberr(hash); return (unsigned int) 0; }
virtual RigiBool isEqual(void* a) const
{Oberr(isEqual); a = NIL;
(void) abort();
return (RigiBool) RigiFalse;}
virtual void Delete_class(ObjectPtr)
{Oberr(delete_type);}
virtual void* Create_class();
virtual void* Duplicate_class();
};
#endif
and chararray.h:
#ifndef CHARARRAYH
#define CHARARRAYH
#ifndef ARRAYOBIDH
#include "array.h"
#endif
#ifndef CHARTYPEH
#include "chartype.h"
#endif
class CharArray;
typedef CharArray* CharArrayPtr;
class CharArray : public Array {
int slot;
public:
// Routines to initialize and destroy the class.
CharArray(unsigned int size = CLTN_DEFAULT_CAPACITY);
CharArray(const CharArray&);
~CharArray();
// Functions that are Required to Use this Class as an Object
// .... all routines the same as in Class Array.......
// Routines that are required by a Collection class and derived classes
// of Collections. [See Array Class for these routines.]
virtual unsigned int size() const {return slot;}
// .... all routines the same as in Class Array.......
// Routines specific to this class
void operator=(const CharArray&);
RigiBool operator==(const CharArray&) const;
void Create(char*);
void Create(char*,int);
void Create(int, char*);
void Add(char*);
void Add(CharType&);
void Addob(RigiObject& ob)
{Array::Add(slot++,&ob);}
void Append(char*);
char* Concat(char);
int FindIndex(char*);
char* Remove()
{return ((CharTypePtr)Array::Remove(--slot))->string();}
ObjectPtr Pop()
{return (Array::Remove(--slot));}
ObjectPtr Look(int i)
{return (Array::At(i));}
void Empty();
virtual unsigned int Size() const
{return slot;}
char* Peek();
char* At(int);
};
#endif
What's wrong with the code?
Assuming that the type RigiBool in the declaration RigiBool operator==(const CharArray&) const; is not defined in one of the headers "array.h" "chartype.h" I think you should include the header containing definition of the type, and just to be sure the "object.h" too.
For cases where a header file uses values of class type variables (not pointers and references) it is recommended to include the headers that contain the class definition. Otherwise a simple forward declaration should be enough.
The types RigiBool, RigiObject and ObjPtr are not available in chararray.h: you need to include object.h (plus whatever else defines RigiBool if CCHeader.h doesn't) -- similarly for RigiBool and RigiFalse in object.h
// somewhere at the top of chararray.h
#include "object.h"
Note: if you define virtual member functions in RigiObject, you should declare the destructor virtual as well
Note: You already have include guards in the #included headers, no need to put them around the #include directives -- doing otherwise indicates (falsely in your case) that you are doing conditional compiling
//chararray.h
#ifndef CHARARRAYH
#define CHARARRAYH
#include "array.h"
#include "chartype.h"
...
//object.h
#ifndef OBJECTH
#define OBJECTH
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <stdlib.h>
#include "CCheader.h"
...
It's hard to say from the little information but I would assume RigiBool is a derived class of RigiObject? When you now reference RigiBool in chararray.h it has to know the RigiObject base class but the RigiObject also needs to know about RigiBool. So you can't declare the base class without knowing the derived RigiBool. Try if forward declaring RigiBool in object.h helps to break the cycle.

Circular Dependencies / Incomplete Types

In C++, I have a problem with circular dependencies / incomplete types. The situation is as follows:
Stuffcollection.h
#include "Spritesheet.h";
class Stuffcollection {
public:
void myfunc (Spritesheet *spritesheet);
void myfuncTwo ();
};
Stuffcollection.cpp
void Stuffcollection::myfunc(Spritesheet *spritesheet) {
unsigned int myvar = 5 * spritesheet->spritevar;
}
void myfunc2() {
//
}
Spritesheet.h
#include "Stuffcollection.h"
class Spritesheet {
public:
void init();
};
Spritesheet.cpp
void Spritesheet::init() {
Stuffcollection stuffme;
myvar = stuffme.myfuncTwo();
}
If I keep the includes as shown above, I get the compiler error
spritesheet has not been declared in Stuffcollection.h (line 4 in
the above). I understand this to be due to a circular dependency.
Now if I change #include "Spritesheet.h" to the Forward
Declaration class Spritesheet; in Stuffcollection.h, I get the
compiler error invalid use of incomplete type 'struct Spritesheet'
in Stuffcollection.cpp (line 2 in the above).
Similarly, if I change #include "Stuffcollection.h" to class
Stuffcollection; in Spritesheet.h, I get the compiler error aggregate
'Stuffcollection stuffme' has incomplete type and cannot be defined
in Spritesheet.cpp (line 2 in the above).
What can I do to solve this problem?
You should include Spritesheet.h in Stuffcollection.cpp
Just use forward declaration in the header file not the cpp file, that solves the circular dependency of the header file. The source file has no circular dependency actually.
Stuffcollection.cpp needs to know the complete layout of class Spritesheet(because you dereference it), So you need to include the header which defines the class Spritesheet in that file.
From your previous Q here, I believe that class Stuffcollection is used in the class declaration of Spritesheet header file and hence the above proposed solution.
Use this form for your nested includes:
Stuffcollection.h
#ifndef STUFFCOLLECTION_H_GUARD
#define STUFFCOLLECTION_H_GUARD
class Spritesheet;
class Stuffcollection {
public:
void myfunc (Spritesheet *spritesheet);
void myfuncTwo ();
};
#endif
Stuffcollection.cpp
#include "Stuffcollection.h"
#include "Spritesheet.h"
void Stuffcollection::myfunc(Spritesheet *spritesheet) {
unsigned int myvar = 5 * spritesheet->spritevar;
}
void Stuffcollection::myfuncTwo() {
//
}
Spritesheet.h
#ifndef SPRITESHEET_H_GUARD
#define SPRITESHEET_H_GUARD
class Spritesheet {
public:
void init();
};
#endif
Spritesheet.cpp
#include "Stuffcollection.h"
#include "Spritesheet.h"
void Spritesheet::init() {
Stuffcollection stuffme;
myvar = stuffme.myfuncTwo();
}
General rules I follow:
Don't include an include from an include, dude. Prefer forward declarations if possible.
Exception: include system includes anywhere you want
Have CPP include everything it needs, not relying upon H recursively including it files.
Always use include guards.
Never use pragma
Spritesheet.h doesn't need to include Stuffcollection.h, since no Stuffcollection is used in the class declaration of Spritesheet. Move that include line to Spritesheet.cpp instead and you should be fine.