declare extern class c++ in hpp file and use it cpp file - c++

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).

Related

redefinition of classes error in c++

I searched through some of the other pages with this same error, but my code does not have any of their issues that I can find.
I have a base class named QBase defined in quadrature.h:
#ifndef SRC_QUADRATURE_H_
#define SRC_QUADRATURE_H_
#include "enum_order.h"
#include "enum_quadrature_type.h"
#include <vector>
#include <memory>
class QBase
{
protected:
QBase (const Order _order=INVALID_ORDER);
public:
virtual ~QBase() {}
virtual QuadratureType type() const = 0;
static std::unique_ptr<QBase> build (const QuadratureType qt, const Order order=INVALID_ORDER);
const std::vector<double> & get_points() const { return _points; }
const std::vector<double> & get_weights() const { return _weights; }
std::vector<double> & get_points() { return _points; }
std::vector<double> & get_weights() { return _weights; }
protected:
const Order _order;
std::vector<double> _points;
std::vector<double> _weights;
};
#endif /* SRC_QUADRATURE_H */
I derive a class QGaussLegendre by QBase definded in gauss_legendre.h
#ifndef SRC_QUADRATURE_GAUSSLEGENDRE_H_
#define SRC_QUADRATURE_GAUSSLEGENDRE_H_
#include "quadrature.h"
class QGaussLegendre : public QBase
{
public:
QGaussLegendre (const Order _order=INVALID_ORDER) : QBase (_order){}
~QGaussLegendre (){}
virtual QuadratureType type() { return QGAUSSLEGENDRE; }
};
#endif /* SRC_QUADRATURE_GAUSSLEGENDRE_H_ */
In the main file I use the build() member function to get points and weights as follows
const Order order = ddp.order;
const QuadratureType qt = ddp.qt;
static std::unique_ptr<QBase> qr(QBase::build(qt,order));
const std::vector<double>& points = qr->get_points();
const std::vector<double>& weights = qr->get_weights();
I don't have any problem till here. Now, the points and weights are defined in the file legendre_gauss.cxx
#include "gauss_legendre.h"
QGaussLegendre::QGaussLegendre(const Order order)
{
switch(order)
{
case CONSTANT:
case FIRST:
{
_points.resize (1);
_weights.resize(1);
_points[0](0) = 0.;
_weights[0]= 2.;
}
}
}
When I compile this last file I get the error:
/home/matteo/flux/gauss_legendre.cxx:13:1:
error: redefinition of ‘QGaussLegendre::QGaussLegendre(qenum::Order)’
QGaussLegendre::QGaussLegendre(const Order order)
^~~~~~~~~~~~~~
In file included from /home/matteo/flux/gauss_legendre.cxx:8:0:
/home/matteo/flux/gauss_legendre.h:25:3:
note: ‘QGaussLegendre::QGaussLegendre(qenum::Order)’ previously
defined here
QGaussLegendre (const Order _order=INVALID_ORDER) : QBase (_order)
^~~~~~~~~~~~~~
Can I do to solve the problem? Thanks a lot.
redefinition of classes error
That's not an error about redefinition of a class. That is an error about redefinition of a function. In particular, redefinition of the function QGaussLegendre::QGaussLegendre(const Order order) which is the contsructor of class QGaussLegendre.
You've defined it first here in quadrature.h:
QGaussLegendre (const Order _order=INVALID_ORDER) : QBase (_order){}
And second time in legendre_gauss.cxx:
QGaussLegendre::QGaussLegendre(const Order order)
{
Can I do to solve the problem?
Solution is to define the function exactly once.

const and non const getter : C2248: cannot access private member declared in class

I have a class which implements a getter to an std::vector. Derived classes are allowed to change the content of the vector, while any other class may read it (or make a copy in my case), but not change it.
SSCCE with Visual Studio 2010 (but should compile with any other as well).
So in the base class I implemented the getter like this:
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstring>
#include <string>
#include <vector>
class X
{
public:
inline std::vector<std::string> const &getChilds(void) const
{
return mChilds;
}
void mutateInternal(void)
{
mState != mState;
}
protected:
inline std::vector<std::string> &getChilds(void)
{
return mChilds;
}
private:
std::vector<std::string> mChilds;
bool mState;
};
// Now in the derived class
class Y : public X
{
public:
Y(void)
{
std::vector<std::string> &childs = getChilds();
childs.push_back("Test");
}
};
// In the non derived class:
class Z
{
public:
void myfunction(void)
{
Y y;
std::vector<std::string> s = y.getChilds();
if(s.size() == 0)
y.mutateInternal();
}
};
int main(int argc, char *argv[])
{
return 0;
}
But I get the error
1>junk.cpp(49): error C2248: "X::getChilds": cannot access private member declared in class.
1> junk.cpp(18): Siehe Deklaration von 'X::getChilds'
1> junk.cpp(10): Siehe Deklaration von 'X'
and I don't really see what is wrong with that and why the compiler doesn't take the public version which is const and instead insists on the non-const.
Even if I change the variable to const &s (which wouldn't help in this case) I still get the same error.
Update:
Edited the SSCCE for calling const and non const functions.
In this case it should be
const Y y;
in Z::my_function for call const version of function.
Live
Or just cast to const Y, like
std::vector<std::string> s = const_cast<const Y&>(y).getChilds();
Your case don't work, since access check will be applied only after overload resolution, in call y.getChilds() non-const overload will be picked, since it has the best match.

Getting error: ISO C++ forbids declaration of with no type

I'm getting the following errors:
ISO C++ forbids declaration of ttTreeInsert with no type
ISO C++ forbids declaration of ttTreeDelete with no type
ISO C++ forbids declaration of ttTreePrint with no type
prototype for int ttTree::ttTreePrint() does not match any in class ttTree
candidate is: void ttTree::ttTreePrint()
Here is my header file:
#ifndef ttTree_h
#define ttTree_h
class ttTree
{
public:
ttTree(void);
int ttTreeInsert(int value);
int ttTreeDelete(int value);
void ttTreePrint(void);
};
#endif
Here is my .cpp file:
#include "ttTree.h"
ttTree::ttTree(void)
{
}
ttTree::ttTreeInsert(int value)
{
}
ttTree::ttTreeDelete(int value)
{
}
ttTree::ttTreePrint(void)
{
}
Can anyone point out what is causing these errors? Thank you!
You forgot the return types in your member function definitions:
int ttTree::ttTreeInsert(int value) { ... }
^^^
and so on.
Your declaration is int ttTreeInsert(int value);
However, your definition/implementation is
ttTree::ttTreeInsert(int value)
{
}
Notice that the return type int is missing in the implementation. Instead it should be
int ttTree::ttTreeInsert(int value)
{
return 1; // or some valid int
}

Error: variable '*' has initializer but incomplete type and one other

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).

C++ Template Class with Template Constructor

I tried to implement Properties in c++. I don't no why but if I want to compile my code there are quite a lot of errors. The main Idea was, that a template class and the tamplate constructor will give the requirement Informations.
I would be grateful if somebody could help me!
Compiling Message:
pi#raspberrypi ~/dev/property $ gcc -std=c++0x -o PropertyTest2 PropertyTest2.cpp
PropertyTest2.cpp:22:16: error: expected ‘;’ at end of member declaration
PropertyTest2.cpp:22:19: error: expected unqualified-id before ‘<’ token
PropertyTest2.cpp: In function ‘int main()’:
PropertyTest2.cpp:34:20: error: use of deleted function ‘PropertyTestClass::PropertyTestClass()’
PropertyTest2.cpp:8:7: error: ‘PropertyTestClass::PropertyTestClass()’ is implicitly deleted because the default definition would be ill-formed:
PropertyTest2.cpp:8:7: error: no matching function for call to ‘Property<int>::Property()’
PropertyTest2.cpp:8:7: note: candidates are:
Property4.cpp:21:2: note: template<int (** G)(), void (** S)(int&)> Property::Property()
Property4.cpp:6:7: note: constexpr Property<int>::Property(const Property<int>&)
Property4.cpp:6:7: note: candidate expects 1 argument, 0 provided
Property4.cpp:6:7: note: constexpr Property<int>::Property(Property<int>&&)
Property4.cpp:6:7: note: candidate expects 1 argument, 0 provided
PropertyTest2.cpp:38:20: error: no matching function for call to ‘Property<int>::Set(int)’
PropertyTest2.cpp:38:20: note: candidate is:
Property4.cpp:30:7: note: void Property<T>::Set(T&) [with T = int]
Property4.cpp:30:7: note: no known conversion for argument 1 from ‘int’ to ‘int&’
Property Class (Property.cpp)
#ifndef __PROPERTY_FH__
#define __PROPERTY_FH__
template <class T>
class Property {
private:
typedef T (*TGetter)(void);
typedef void (*TSetter)(T &);
TGetter Getter;
TSetter Setter;
public:
typedef T type;
template<TGetter *G,
TSetter *S
>
Property() {
this->Getter = G;
this->Setter = S;
}
T Get(void) {
return (this->Getter)();
}
void Set(T &value) {
(this->Setter)(value);
}
};
#endif
Testing file (PropertyTest.cpp):
#ifndef __PROPERTY_TEST_FH__
#define __PROPERTY_TEST_FH__
#include <iostream>
#include "Property.cpp"
class PropertyTestClass {
private:
// ReadWrite Property for age
int _age;
int AgeGetter(void) {
return this->_age;
}
void AgeSetter(int &value) {
this->_age = value;
}
public:
// ReadWrite Property for age
Property<int> age<&PropertyTestClass::AgeGetter, &PropertyTestClass::AgeSetter>;
};
#endif
/**
* Program Entry
**/
int main() {
std::cout << "Property Test Programm\n\n";
PropertyTestClass propTest;
std::cout << "ReadWrite Property for age\n";
propTest.age.Set(5);
std::cout << propTest.age.Get() << "\n";
return 0;
}
Ok, this time fixed all the problems in your code.
Property.cpp:
#ifndef __PROPERTY_FH__
#define __PROPERTY_FH__
#include <boost/function.hpp>
template <class T>
class Property {
private:
typedef boost::function <T()> TGetter;
typedef boost::function <void(const T&)> TSetter;
TGetter Getter;
TSetter Setter;
public:
typedef T type;
Property(TGetter G, TSetter S) {
this->Getter = G;
this->Setter = S;
}
T Get(void) {
return (this->Getter)();
}
void Set(const T &value) {
(this->Setter)(value);
}
};
#endif
PropertyTests.cpp:
#ifndef __PROPERTY_TEST_FH__
#define __PROPERTY_TEST_FH__
#include <iostream>
#include <boost/bind.hpp>
#include "Property.cpp"
class PropertyTestClass {
private:
// ReadWrite Property for age
int _age;
int AgeGetter() {
return this->_age;
}
void AgeSetter(const int &value) {
this->_age = value;
}
public:
// ReadWrite Property for age
Property<int> age;
PropertyTestClass() : age(
boost::bind(&PropertyTestClass::AgeGetter, this),
boost::bind(&PropertyTestClass::AgeSetter, this, _1))
{}
};
#endif
/**
* Program Entry
**/
int main() {
std::cout << "Property Test Programm\n\n";
PropertyTestClass propTest;
std::cout << "ReadWrite Property for age\n";
propTest.age.Set(5);
std::cout << propTest.age.Get() << "\n";
return 0;
}
Output:
$ ./a.out
Property Test Programm
ReadWrite Property for age
5