redefinition of classes error in c++ - 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.

Related

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

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

C++ Builder Pattern with Forward Declaration [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I recently got stuck in a situation. In the first version, everything is implemented in header file and it works fine. In the second version when i tried to separate implementation from header declarations, I got many errors. In the below lines, i m going to demonstrate problem. Thanks in advance..
First Version (it works fine!)
cameravalue.h
#ifndef CAMERAVALUE_H
#define CAMERAVALUE_H
#include <string>
class CameraValue
{
private:
class CameraProperties
{
private:
CameraProperties()
: mId(-1),
mName(),
mAddress(),
mExposure(),
mFocus()
{}
int mId;
std::string mName;
std::string mAddress;
std::string mExposure;
long long mFocus;
friend class CameraValue;
friend class CameraBuilder;
};
public:
class CameraBuilder
{
public:
CameraBuilder(int id)
{
mProperties.mId = id;
}
CameraBuilder& setName(std::string& name)
{
mProperties.mName = name;
return *this;
}
CameraBuilder& setAddress(std::string& adress)
{
mProperties.mAddress = adress;
return *this;
}
CameraBuilder& setExposure(std::string& exposure)
{
mProperties.mExposure = exposure;
return *this;
}
CameraBuilder& setFocus(int focus)
{
mProperties.mFocus = focus;
return *this;
}
CameraValue build()
{
return CameraValue(mProperties);
}
private:
CameraProperties mProperties;
};
private:
CameraValue(const CameraProperties& properties)
:mProperties(properties)
{}
CameraProperties mProperties;
};
#endif // CAMERAVALUE_H
main.cpp
#include "cameravalue.h"
#include <iostream>
int main(int argc, char *argv[])
{
CameraValue cm = CameraValue::CameraBuilder(1).setName(std::string("Huseyin")).build();
return 0;
}
Second Version (Don't work)
cameravalue.h
#ifndef CAMERAVALUE_H
#define CAMERAVALUE_H
#include <string>
class CameraValue
{
private:
class CameraProperties;
public:
class CameraBuilder;
private:
CameraValue(const CameraProperties& properties);
CameraProperties mProperties;
};
#endif // CAMERAVALUE_H
cameravalue.cpp
#include "cameravalue.h"
#include <string>
class CameraValue::CameraProperties
{
private:
CameraProperties()
: mId(-1),
mName(),
mAddress(),
mExposure(),
mFocus()
{}
int mId;
std::string mName;
std::string mAddress;
std::string mExposure;
long long mFocus;
friend class CameraValue;
friend class CameraBuilder;
};
class CameraValue::CameraBuilder
{
public:
CameraBuilder(int id)
{
mProperties.mId = id;
}
CameraBuilder& setName(std::string& name)
{
mProperties.mName = name;
return *this;
}
CameraBuilder& setAddress(std::string& adress)
{
mProperties.mAddress = adress;
return *this;
}
CameraBuilder& setExposure(std::string& exposure)
{
mProperties.mExposure = exposure;
return *this;
}
CameraBuilder& setFocus(int focus)
{
mProperties.mFocus = focus;
return *this;
}
CameraValue build()
{
return CameraValue(mProperties);
}
private:
CameraProperties mProperties;
};
CameraValue::CameraValue(const CameraProperties& properties)
: mProperties(properties)
{}
main.cpp
#include "cameravalue.h"
#include <iostream>
int main(int argc, char *argv[])
{
CameraValue cm = CameraValue::CameraBuilder(1).setName(std::string("Huseyin")).build();
return 0;
}
Compile Errors
cameravalue.cpp
c:\users\huseyin\documents\builderpattern\cameravalue.h(20) : error
C2079: 'CameraValue::mProperties' uses undefined class
'CameraValue::CameraProperties' ..\BuilderPattern\cameravalue.cpp(74)
: error C2440: 'initializing' : cannot convert from 'const
CameraValue::CameraProperties' to 'int'
No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
..\BuilderPattern\cameravalue.cpp(74) : error C2439:
'CameraValue::mProperties' : member could not be initialized
c:\users\huseyin\documents\builderpattern\cameravalue.h(20) : see declaration of 'CameraValue::mProperties'
c:\users\huseyin\documents\builderpattern\cameravalue.h(20) : error
C2079: 'CameraValue::mProperties' uses undefined class
'CameraValue::CameraProperties' ..\BuilderPattern\main.cpp(9) : error
C2440: '<function-style-cast>' : cannot convert from 'int' to
'CameraValue::CameraBuilder'
Source or target has incomplete type ..\BuilderPattern\main.cpp(9) : error C2228: left of '.setName' must
have class/struct/union ..\BuilderPattern\main.cpp(9) : error C2228:
left of '.build' must have class/struct/union
..\BuilderPattern\main.cpp(9) : error C2512: 'CameraValue' : no
appropriate default constructor available
..\BuilderPattern\main.cpp(10) : error C2039: 'getName' : is not a
member of 'CameraValue'
c:\users\huseyin\documents\builderpattern\cameravalue.h(8) : see declaration of 'CameraValue'
Definition of class CameraBuilder should be visible in main.cpp, so you can't just forward-declare it in cameravalue.h. But you can make the definitions of its member functions out-of-line:
// cameravalue.h
class CameraValue {
class CameraBuilder {
public:
CameraBuilder(int id);
...
};
};
// cameravalue.cpp
CameraValue::CameraBuilder::CameraBuilder(int id) {
...
}

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.

Returning a map of structs from within a class (where the struct definition is within the class): compile error

I have a class, and within that class I define a struct. The struct has overloaded comparison operators so that it can be used with a map (with an int as the key).
Prior to messing with classes, I had the struct defined in a .cc file, and that file also contained a function which returned a map of this struct. It worked.
Now I want to have the struct defined in the class header, and the class should have a function which returns a map of structs.
Here is a simplified version of my code, which compiles with the same error as the full version. I don't understand the error, and would appreciate any help!
Cheers.
myclass.h:
#include <map>
class myclass {
public:
struct mystruct {
int i;
mystruct();
mystruct(int j);
bool operator==(const mystruct& rhs);
bool operator>(const mystruct& rhs);
bool operator<(const mystruct& rhs);
};
::std::map<int,mystruct> getStructMap();
};
myclass.cc:
#include <map>
#include "myclass.h"
myclass::mystruct::mystruct(int j) : i(j) {};
myclass::mystruct::mystruct() : i(-1) {};
bool ::myclass::mystruct::operator==(const ::myclass::mystruct& rhs) {return i==rhs.i; }
bool ::myclass::mystruct::operator>(const ::myclass::mystruct& rhs) {return i>rhs.i; }
bool ::myclass::mystruct::operator<(const ::myclass::mystruct& rhs) {return i<rhs.i; }
::std::map<int,::myclass::mystruct> ::myclass::getStructMap() {
::std::map<int,::myclass::mystruct> structMap;
for (int i=0;i<5;i++) structMap[i]=::myclass::mystruct(i);
return structMap;
}
myprogram.cc:
#include <iostream>
#include <map>
#include "myclass.h"
int main() {
myclass myobj;
::std::map<int,::myclass::mystruct> mymap;
mymap=myobj.getStructMap();
}
compile error:
> g++ -o myprogram myprogram.cc myclass.cc
myclass.cc:12: error: ‘class std::map<int, myclass::mystruct, std::less<int>,std::allocator<std::pair<const int, myclass::mystruct> > >::myclass’ has not been declared
myclass.cc:12: error: ISO C++ forbids declaration of ‘getStructMap’ with no type
myclass.cc: In function ‘int getStructMap()’:
myclass.cc:15: error: cannot convert ‘std::map<int, myclass::mystruct, std::less<int>, std::allocator<std::pair<const int, myclass::mystruct> > >’ to ‘int’ in return
Currently your code in parsed as
/*missing type*/ ::std::map<int,::myclass::mystruct>::myclass::getStructMap()
Thus, first error, map doesn't have myclass member (or subclasses, method, typedef, ...)
then the second error : no return type (so assuming int and thus the conversion error).
So to solve that, in myclass.cc, you may remove extra :: as follow:
::std::map<int,::myclass::mystruct> myclass::getStructMap() {
or add extra parenthesis:
::std::map<int,::myclass::mystruct> (::myclass::getStructMap()) {

Arranging template related code in different headers

The code below works as long as I keep it all in the "main.cpp" file.
//#include "Travel.h"
//#include "Obj.h"
// "Travel.h"
typedef int travel_t;
class Travel
{
public:
static const travel_t AIR;
static const travel_t WATER;
static const travel_t LAND;
};
// "Travel.cpp"
// #ifndef TRAVEL_H
// #define TRAVEL_H
//
// #include "Travel.h"
const travel_t Travel::AIR = -2;
const travel_t Travel::WATER = -1;
const travel_t Travel::LAND = 0;
// #endif //TRAVEL_H
// "Obj.h"
// #ifndef OBJ_H
// #define OBJ_H
//
//#include "Travel.h"
template<typename T, travel_t travel>
class Obj
{
public:
void foo(){};
};
// #endif //OBJ_H
// "main.cpp"
int main()
{
Obj<int, Travel::AIR> objAirTravel;
objAirTravel.foo();
return 0;
}
However, as soon as I moved code to different headers and implementation files as indicated, it doesn't compile any more. :-( How can I fix that problem? What is the problem/rule behind it? This is the compiler error I get (using gcc):
main.cpp|45|error: 'Travel::AIR' is not a valid template argument for type 'int' because it is a non-constant expression|
main.cpp|45|error: invalid type in declaration before ';' token|
main.cpp|47|error: request for member 'foo' in 'objAirTravel', which is of non-class type 'int'|
In order to use a constant as a template argument, its value must be available in the current translation unit. When you move the definition of Travel::Air to a different source file, its value is no longer available to the compiler in main.
Since it's an integer constant, you can declare the value in the declaration inside the class:
class Travel
{
public:
static const travel_t AIR = -2;
static const travel_t WATER = -1;
static const travel_t LAND = 0;
};
Now the values are available to use as template arguments in any translation unit that includes this class definition.