I have recently started working with C++ classes and had just started when I reached an error. I have a "resource.h" file that contains the class definition of two classes: 'deck' and 'card'. I #included this file in another file, "card.cpp". In the card.cpp file I described all the methods/functions of the 'card' class. However on compilation I am getting the following the errors (fyi I am using the MinGW compiler for command-line):
card.cpp:3:29: error: ISO C++ forbids declaration of 'setCard' with no
type [-fp ermissive] card.cpp:3:1: error: prototype for 'int
Card::setCard(char, char)' does not matc h any in class 'Card'
resource.h:9:8: error: candidate is: void Card::setCard(char, char)
The "card.cpp" file:
#include "resource.h"
Card::setCard(char f, char s) {
face = f;
suit = s;
}
Card::Card (char face, char suit) {
setCard(face, suit);
}
Card::~Card () {}
The "resource.h" file:
typedef unsigned short int UINT;
class Card;
class Deck;
class Card {
public:
Card(char face, char suit);
~Card();
void setCard(char face, char suit);
char getFace() const { return face; }
char getSuit() const { return suit; }
private:
char face;
char suit;
};
class Deck {
public:
Deck();
~Deck();
Card getCard(UINT x);
private:
Card myCards[54];
};
What is causing this issue, and why in the world does the compiler think that "Card::setChard()" is an int
Card::setCard(char f, char s) {
face = f;
suit = s;
}
should be
void Card::setCard(char f, char s) {
face = f;
suit = s;
}
Some hints that helped me get to this amazing conclusion:
C++ forbids declaration of 'setCard' with no type
candidate is: void Card::setCard(char, char)
If you thought this was cryptic, hold on tight for when you get to templates. Compilers have a history of generating great error messages for them.
Related
I have two classes : Individu and Cite and as u can see Individu is defined before
//file.hpp
#include <iostream>
#include <stdexcept>
#include <vector>
extern Cite CITE;
class Individu {
protected:
static int id;
TYPE t;
public:
Individu();
virtual ~Individu();
static int & getCompteur();
virtual void afficher(std::ostream& ) const;
virtual TYPE getType() const;
};
class Cite {
std::vector<const Individu *> tab;
public:
Cite();
~Cite();
void addPersonne(const Individu *);
int size() const;
};
std::ostream& operator<<(std::ostream&, const Individu& );
#endif
I need to add an Individu one it's instanciated to the tab vector of Cite and sisnce there is just one Cite I declared Exctern CITE Cite to work with just like that :
// file.cpp
#include <algorithm>
#include "file.hpp"
int Individu::id = 0;
Individu::Individu() {
CITE.addPersonne(*this);
id++;
}
Individu::~Individu(){
}
int& Individu::getCompteur() {
return id;
}
void Individu::afficher(std::ostream& o) const{
o << id;
}
void Personne::afficher(std::ostream& o) const {
o << nom << " " << id;
}
std::ostream& operator<<(std::ostream& o, const Individu& i ){
i.afficher(o);
return o;
}
TYPE Individu::getType() const {
throw IllegalException();
}
Cite::Cite(){
}
Cite::~Cite() {
}
void Cite::addPersonne(const Individu * i){
tab.push_back(i);
}
int Cite::size() const {
return tab.size();
}
and when I compile I got this error :
file.hpp:13:8: error: ‘Cite’ does not name a type
13 | extern Cite CITE;
| ^~~~
file.cpp: In constructor ‘Individu::Individu()’:
file.cpp:30:5: error: ‘CITE’ was not declared in this scope
30 | CITE.addPerconne(*this);
| ^~~~
make: *** [makefile:15 : build/deviant.o] Erreur 1
I understand that Cite is not yet defined so that's why I got that error , so hwo can I fix it ?
You have two issues in your code:
extern Cite CITE is declared before the class Cite is defined, so the compiler doesn't know what a Cite is at that point. You should move this declaration after the definition of Cite.
You never define CITE. An extern variable declaration is a promise to the compiler that you will define that variable later. You're essentially saying "I promise a Cite object named CITE exists even though you can't see it right now". You broke that promise by never actually creating that object. You need to define a Cite CITE somewhere (most likely in file.cpp).
While compile the below code got compilation error as
rise.h: error: pointer to incomplete class type is not allowed (fall->value = id)
While I added the function definition in dot cpp file, got linking error.
Note: Its working fine without inline.
File: fall.h
#include<rise.h>
class Fall
{
public:
char value;
};
File: rise.h
#include<fall.h>
class Fall;
class Rise
{
public:
Fall *fall;
inline void fill_the_val(struct ring *buf, char flag=false, char id = 0)
{
if(true == flag)
{
fall->value = id; //this line got compilation issue
}
}
};
File: rise.cpp
#include<fall.h>
#include<rise.h>
int main()
{
fill_the_val(buf, true, 1);
}
I know there are a couple other questions on this specific question, but nothing that I can find on it seems to work, so I'm posting my specific code.
Here is the code:
#ifndef __MEMORY_TRACKER_H__
#define __MEMORY_TRACKER_H__
#include <unordered_map>
namespace cige
{
namespace memory
{
class CIGE_API MemoryTracker
{
protected:
typedef struct AllocRecord
{
size_t bytes;
std::string filename;
size_t line;
std::string func;
AllocRecord() :
bytes(0), line(0)
{ }
AllocRecord(size_t sz, const char* file, size_t ln, const char* fun) :
bytes(sz), line(ln)
{
if (file)
filename = file;
if (fun)
func = fun;
}
} AllocRecord;
std::string m_leakFileName;
bool m_dumpToConsole;
typedef std::unordered_map<void*, AllocRecord> AllocMap;
AllocMap m_allocationMap;
size_t m_totalAllocations;
bool m_recordEnable;
protected:
void reportLeaks();
MemoryTracker() :
m_leakFileName("CIGEMemory.log"), m_dumpToConsole(true), m_totalAllocations(0), m_recordEnable(true)
{ }
public:
void setReportFileName(const std::string& name)
{
m_leakFileName = name;
}
const std::string& getReportFileName() const
{
return m_leakFileName;
}
void setReportToConsoleOutput(bool b)
{
m_dumpToConsole = b;
}
bool getReportToConsoleOutput() const
{
return m_dumpToConsole;
}
void setRecordEnable(bool b)
{
m_recordEnable = b;
}
bool getRecordEnable() const
{
return m_recordEnable;
}
size_t getTotalMemoryAllocated() const
{
return m_totalAllocations;
}
void _recordAlloc(void* ptr, size_t sz, const char* file = nullptr, size_t ln = 0, const char* fun = nullptr);
void _recordDealloc(void* ptr);
~MemoryTracker()
{
reportLeaks();
}
static MemoryTracker& get();
};
}
}
#endif // __MEMORY_TRACKER_H__
I'm getting: variable 'cige::memory::CIGE_API cige::memory::MemoryTracker' has initializer but incomplete type at the line with the class declaration. I've looked all over and I cant find any answers that have fixed this issue.
I'm also having the error expected '}' or ',' or ';' before 'protected' at the line with protected, right above the struct.
Any help with either of these two errors would be appreciated.
EDIT: CIGE_API is defined in a separate file (which is included), as __declspec(dllexport).
EDIT2: I fixed my problem (see the answer below). It was basically just Code::Blocks derping out pretty bad.
Looks like CIGE_API is not defined. So compiler try to resolve it like variable declaration class Type Variable {initializer-list}, where Type is CIGE_API and Variable is MemoryTracker.
In other words, syntactically you're predeclaring CIGE_API type and creating variable of this type instead of defining a class.
The definition
class CIGE_API MemoryTracker { ... };
is not valid C++. I guess CIGE_API is a macro defined to an implementation specific extension, but you didn't include the corresponding header which defines that macro.
Ok I ended up fixing my own problem. Code::Blocks wasn't properly finding files that were in my project (about the third time this has happened).
In entirely unrelated news, does anyone know another cross-platform IDE that works well for C++? (I already know about Eclipse).
I have started learning C++, and have gotten stuck when working with multiple files. To practice basic classes, I wrote three different files,
working.cpp
word.cpp
word.h
word.cpp:
#include <iostream>
#include "word.h"
using namespace std;
class word{
public:
char *word;
void createWord(char *str)
{
word = str;
}
void print_word(void)
{
cout<<word<<endl;
}
char * getWord()
{
return word;
}
}
working.cpp
#include <iostream>
#include "word.h"
void printWord(word);
using namespace std;
int main()
{
word one;
one.createWord("one");
printWord(one);
}
void printWord(word a)
{
cout<<a.getWord()<<endl;
}
word.h
class word;
These are three different files, so I am not sure how to compile them. What I have tried is
g++ working.cpp word.cpp
However, the compiler doesn't recognize word as a class, and gives me the following errors
working.cpp: In function 'int main()':
working.cpp:7:7: error: aggregate 'word one' has incomplete type and cannot be defined
working.cpp:7:12: error: aggregate 'word two' has incomplete type and cannot be defined
working.cpp:7:17: error: aggregate 'word three' has incomplete type and cannot be defined
working.cpp: In function 'void printWord(word)':
working.cpp:19:6: error: 'aha' has incomplete type
In file included from working.cpp:2:0:
word.h:2:7: error: forward declaration of 'class word'
word.cpp:25:1: error: expected ';' after class definition
What am I doing wrong while compiling?
You need to include more of the definition of word in the header file. Something like this:
class word
{
public:
char *word;
void createWord(char *str);
void print_word(void);
char * getWord();
};
Then, change word.cpp to just have the implementations:
void word::createWord(char *str)
{
word = str;
}
void word::print_word(void)
{
cout<<word<<endl;
}
char * word::getWord()
{
return word;
}
compile and link!
You need to have more of the word class in the header so that your other translation unit can know how big the class is (to reserve enough space for the instance you're creating) as well as to know the names of the methods you want to call.
Just mentioning the class name in the header file (a so-called forward declaration) is not enough; you need a complete class declaration (which declares all the fields and functions of the class):
class word {
public:
char *word;
void createWord(char *str);
void print_word(void);
char * getWord();
};
There is no actual declaration of class word in word.h
word.h:2:7: error: forward declaration of 'class word'
I would advise you to read Bjarne Stroustrup's brilliant book "The C++ Programming Language" to get started.
I try to make class where I can creat new object of Student.
I've got some problem with definition of class body (student.cpp) and class (student.h).
Error:
In file included from student.cpp:1:
student.h:21:7: warning: no newline at end of file
student.cpp:6: error: prototype for `Student::Student()' does not match any in class `Student'
student.h:6: error: candidates are: Student::Student(const Student&)
student.h:8: error: Student::Student(char*, char*, char*, char*, int, int, bool)
student.cpp
//body definition
#include "student.h"
#include <iostream>
Student::Student()
{
m_imie = "0";
m_nazwisko = "0";
m_pesel = "0";
m_indeks = "0";
m_wiek = 0;
m_semestr = 0;
m_plec = false;
}
student.h
//class definition without body
#include <string.h>
class Student {
//konstruktor domyslny
Student (char* imie, char* nazwisko, char* pesel, char* indeks, int wiek, int semestr, bool plec):
m_imie(imie), m_nazwisko(nazwisko), m_pesel(pesel), m_indeks(indeks), m_wiek(wiek), m_semestr(semestr), m_plec(plec)
{}
private:
char* m_imie;
char* m_nazwisko;
char* m_pesel;
char* m_indeks;
int m_wiek;
int m_semestr;
bool m_plec;
};
Your constructor in cpp file does not match constructor in header.
Every constructors/desctructors/methods realizations in cpp should be first defined in class in header.
If you want to have 2 constructors - 1 with no parameters and one with many parameters as you have. You need to add definition of your constructor in header.
//class definition without body
#include <string.h>
class Student {
//konstruktor domyslny
Student (char* imie, char* nazwisko, char* pesel, char* indeks, int wiek, int semestr, bool plec):
m_imie(imie), m_nazwisko(nazwisko), m_pesel(pesel), m_indeks(indeks), m_wiek(wiek), m_semestr(semestr), m_plec(plec)
{} //here really implementation made
Student(); //one more constructor without impementation
private:
char* m_imie;
char* m_nazwisko;
char* m_pesel;
char* m_indeks;
int m_wiek;
int m_semestr;
bool m_plec;
};
In you header file you declare that Student has just one constructor with all the written parameters but no default Student() constructor, you should add it to header:
class Student {
Student();
Student(char* imie, char* nazwisko ... ) {}
};
You wrote a body for a Student constructor that doesn't take any parameters:
Student::Student( /* NO PARAMETERS */ )
But this function, Student(), is not in the class-definition.
This generates the error:
prototype for `Student::Student()' does not match any in class `Student'
You need to write:
class Student {
public:
Student(); /* NOW it is declared as well as defined */
[... all the other stuff ...]
};
Now, there is both a prototype for Student() and also for Student(/* 7 parameters */)
The fix for the other error is simple:
student.h:21:7: warning: no newline at end of file
The fix is to put a newline at the end of the file! :-)