I'm having some difficulties with friend functions in C++, but my suspicion is that is more of a symptom of a problem I have with preprocessor directives and #include.
This is a silly example of what I was doing. Five files: bobby.h, bobby.cpp, billy.h, billy.cpp, and main.cpp. Billy has a protected function called ReceiveMoney. Bobby has a function called bank that calls Billy's ReceiveMoney. i.e. every time Bobby goes to the bank he splits the money with Billy.
billy.h
#ifndef BILLY_H
#define BILLY_H
#include "bobby.h"
class Billy
{
friend void Bobby::Bank(int, Billy &);
public:
Billy();
protected:
void ReceiveMoney(int inc);
private:
int money;
};
#endif
billy.cpp
#include "billy.h"
Billy::Billy()
{
money = 0;
}
void Billy::ReceiveMoney(int inc)
{
money+=inc;
}
bobby.h
#ifndef BOBBY_H
#define BOBBY_H
#include "billy.h"
class Bobby
{
public:
Bobby();
void Bank(int amount, Billy & b);
protected:
int money;
};
#endif
bobby.cpp
#include "bobby.h"
Bobby::Bobby()
{
money = 0;
}
void Bobby::Bank(int amount, Billy & b)
{
b.ReceiveMoney(amount/2);
}
main.cpp
#include "billy.h"
#include "bobby.h"
int main()
{
Bobby bo;
Billy bi;
bo.Bank(150, bi);
return 0;
}
I get a large number of errors, usually
error C2653: 'Bobby' : is not a class or namespace name
or
error C2653: 'Billy' : is not a class or namespace name
I'm doing this in an empty console project in VS0
You have a Circular dependency of header files.
billy.h includes bobby.h, while bobby.h includes billy.h.
Obviously, the compiler cannot make out the types due to this circular dependency.
The best solution is to rethink your design and avoid the circular dependency or
Use Forward declarations to break the circular dependency.
Just forward declare class Billy in bobby.h
//#include "billy.h" <----- You don't need this include
class Billy; <----- Just Forward Declaration should suffice
You can use a forward declaration here because, Declare functions or methods which accepts/return incomplete types, in this case Billy is an Incomplete type for the compiler.
There is a loop in your #include, you cannot do that. You must use a forward declaration of Bobby in billy.h. Such as class Bobby;. You won't be able to declare the friend function even with that.
The only real solution is to avoid the need for a friend. ReceiveMoney should be public in fact: if Bobby represents something like an account, it is logical.
The constraints on friend makes it useful only to solve inner behaviour of classes (for example with collections and nodes implementing them).
Due to circular dependency none of the classes are fully defined. hence the large number of errors. If possible change your design and inherit or include only things necessary. As mentioned by Als forward declarations can be a choice.
Circular dependencies mostly arise due to design faults.
Related
I am developing a project in which I have a vendor library, say vendor.h, for the specific Arduino-compatible board I'm using which defines class HTTPClient that conflicts with an Arduino system library, HTTPClient.h, which also defines class HTTPClient.
These two classes are unrelated other than having the same name, and the vendor implementation of an HTTP client is far less capable than the Arduino system library's implementation, so I'd prefer to use the latter. But I can't omit including the former, because I need quite a bit from the vendor.h. Essentially, I have the problem posed here, but with classes rather than functions. I have the full code of both, but given that one is a system library and the other is a vendor library, I'm reluctant to fork and edit either, as that adds lots of merging work down the road if either of them are updated, so my preference would be to find a tidy solution that doesn't edit either header.
I've tried a variety of solutions posted in other SO questions:
I do not want to leave out either header, as I need vendor.h for quite a few things and need the capabilities of HTTPClient.h's client implementation
Proper namespaces in the headers would solve the problem, I would prefer to avoid editing either header
I tried wrapping the #include <HTTPClient.h> in a namespace in my main.cpp, but that caused linking errors, as it's not a header-only library, so the header & cpp weren't in the same namespace
I tried a simple wrapper as proposed for the function in the above linked SO question in which the header contained just a forward declaration of my wrapper class & the associated cpp contained the actual class definition. This gave a compiler error of error: aggregate 'HTTP::Client client' has incomplete type and cannot be defined (Code sample of this attempt below)
main.cpp:
#include <vendor.h>
#include "httpclientwrapper.h"
HTTP::Client client;
httpclientwrapper.h:
#ifndef INC_HTTPCLIENTWRAPPER_H
#define INC_HTTPCLIENTWRAPPER_H
namespace HTTP {
class Client;
}
#endif
httpclientwrapper.cpp:
#include "httpclientwrapper.h"
#include <HTTPClient.h>
namespace HTTP {
class Client : public ::HTTPClient {};
}
In that example, I can't inherit from HTTPClient in a class definition in my header, as that will reintroduce the duplicate class name to the global namespace in my main program (hence the perhaps misguided attempt to see if a forward declaration would do the trick). I suspect that I can resolve the issue by completely duplicating the class definition of HTTPClient in my wrapper class above rather than trying to use inheritance. I would then add member definitions to my wrapper cpp which pass the call to HTTPClient's members. Before I go through the trouble of rewriting (or more likely, copy/pasting) the entire HTTPClient definition from HTTPClient.h into my own wrapper, I was wondering if there was a better or more proper way to resolve the conflict?
Thanks for you help!
As a solution was never proposed, I'm posting an answer that summarizes my research and my ultimate resolution. Mostly, I encourage the use of namespaces, because proper uses of namespaces would have eliminated the conflict. However, Arduino environments try to keep things simple to lower the barrier of entry, eschewing "complicated" features of C++, so more advanced use cases will likely continue to run into issues like this. From other SO answers and forum posts (cited where I could), here are some methods for avoiding name conflicts like this:
If you can edit the source
Edit the source code to remove the conflict or add a namespace to one of both libraries. If this is an open source library, submit a pull request. This is the cleanest solution. However, if you can't push your changes back upstream (such as when one is a system library for some hardware), you may end up with merge issues down the road when the maintainer/developer updates the libraries.
If you can't edit the source
Credit for part of this: How to avoid variable/function conflicts from two libraries in C++
For libraries that are header only libraries (or all functions are inline)
(ie, they have only a .h file without a .o or .cpp)
Include the library inside a namespace. In most code, this is frowned upon as poor form, but if you're already in a situation where you are trying to cope with a library that doesn't contain itself nicely, it's a clean and simple way to contain the code in a namespace and avoid name conflicts.
main.cpp
namespace foo {
#include library.h
}
int main() {
foo::bar(1);
}
For libraries with functions
The above method will fail to link at compile time, because the declarations in the header will be inside the namespace, but the definitions of those functions are not.
Instead, create a wrapper header and implementation file. In the header, declare your namespace and functions you wish to use, but do not import the original library. In the implementation file, import your library, and use the functions inside your new namespaced functions. That way, the one conflicting library is not imported into the same place as the other.
wrapper.h
namespace foo {
int bar(int a);
}
wrapper.cpp
#include "wrapper.h"
#include "library.h"
namespace foo {
int bar(int a) {
return ::bar(a);
}
}
main.cpp
#include "wrapper.h"
int main() {
foo::bar(1);
}
You could also, for the sake of consistency, wrap both libraries so they're each in their own namespace. This method does mean that you will have to put in the effort to write a wrapper for every function you plan to use. This gets more complicated, however, when you need to use classes from the library (see below).
For libraries with classes
This is an extension of the wrapper function model from above, but you will need to put in more work, and there are a few more drawbacks. You can't write a class that inherits from the library's class, as that would require importing the original library in your wrapper header prior to defining your class, so you must write a complete wrapper class. You also cannot have a private member of your class of the type from the original class that you can delegate calls to for the same reason. The attempt at using a forward declaration I described in my question also did not work, as the header file needs a complete declaration of the class to compile. This left me the below implementation, which only works in the cases of a singleton (which was my use case anyway).
The wrapper header file should almost completely duplicate the public interface of the class you want to use.
wrapper.h
namespace foo {
Class Bar() {
public:
void f(int a);
bool g(char* b, int c, bool d);
char* h();
};
}
The wrapper implementation file then creates an instance and passes the calls along.
wrapper.cpp
#include "wrapper.h"
#include "library.h"
namespace foo {
::Bar obj;
void Bar::f(int a) {
return obj.f(a);
}
bool Bar::g(char* b, int c, bool d) {
return obj.g(b, c, d);
}
char* Bar::h() {
return obj.h();
}
}
The main file will interact with only a single instance of the original class, no matter how many times your wrapper class in instantiated.
main.cpp
#include "wrapper.h"
int main() {
foo::Bar obj;
obj.f(1);
obj.g("hello",5,true);
obj.h();
}
Overall, this strikes me as a flawed solution. To fully wrap this class, I think the this could be modified to add a factory class that would be fully contained inside the wrapper implementation file. This class would instantiate the original library class every time your wrapper class is instantiated, and then track these instances. In this way, your wrapper class could keep an index to its associated instance in the factory and bypass the need to have that instance as its own private member. This seemed like a significant amount of work, and I did not attempt to do so, but would look something like the code below. (This probably needs some polish and a real look at its memory usage!)
The wrapper header file adds a constructor & private member to store an instance id
wrapper.h
namespace foo {
Class Bar() {
public:
Bar();
void f(int a);
bool g(char* b, int c, bool d);
char* h();
private:
unsigned int instance;
};
}
The wrapper implementation file then adds a factory class to manage instances of the original library's class
wrapper.cpp
#include "wrapper.h"
#include "library.h"
namespace foo {
class BarFactory {
public:
static unsigned int new() {
instances[count] = new ::Bar();
return count++;
}
static ::Bar* get(unsigned int i) {
return instances[i];
}
private:
BarFactory();
::Bar* instances[MAX_COUNT]
int count;
};
void Bar::Bar() {
instance = BarFactory.new();
}
void Bar::f(int a) {
return BarFactory.get(i)->f(a);
}
bool Bar::g(char* b, int c, bool d) {
return BarFactory.get(i)->g(b, c, d);
}
char* Bar::h() {
return BarFactory.get(i)->h();
}
}
The main file remains unchanged
main.cpp
#include "wrapper.h"
int main() {
foo::bar obj;
obj.f(1);
obj.g("hello",5,true);
obj.h();
}
If all of this seems like a lot of work, then you're thinking the same thing I did. I implemented the basic class wrapper, and realized it wasn't going to work for my use case. And given the hardware limitations of the Arduino, I ultimately decided that rather than add more code to be able to use the HTTPClient implementation in either library, I wrote my own HTTP implementation library in the end, and so used none of the above and saved several hundred kilobytes of memory. But I wanted to share here in case somebody else was looking to answer the same question!
I can't solve this circular dependency problem; always getting this error:
"invalid use of incomplete type struct GemsGame"
I don't know why the compiler doesn't know the declaration of GemsGame even if I included gemsgame.h
Both classes depend on each other (GemsGame store a vector of GemElements, and GemElements need to access this same vector)
Here is partial code of GEMELEMENT.H:
#ifndef GEMELEMENT_H_INCLUDED
#define GEMELEMENT_H_INCLUDED
#include "GemsGame.h"
class GemsGame;
class GemElement {
private:
GemsGame* _gemsGame;
public:
GemElement{
_gemsGame = application.getCurrentGame();
_gemsGame->getGemsVector();
}
};
#endif // GEMELEMENT_H_INCLUDED
...and of GEMSGAME.H:
#ifndef GEMSGAME_H_INCLUDED
#define GEMSGAME_H_INCLUDED
#include "GemElement.h"
class GemsGame {
private:
vector< vector<GemElement*> > _gemsVector;
public:
GemsGame() {
...
}
vector< vector<GemElement*> > getGemsVector() {
return _gemsVector;
}
}
#endif // GEMSGAME_H_INCLUDED
Remove the #include directives, you already have the classes forward declared.
If your class A needs, in its definition, to know something about the particulars of class B, then you need to include class B's header. If class A only needs to know that class B exists, such as when class A only holds a pointer to class B instances, then it's enough to forward-declare, and in that case an #include is not needed.
If you deference the pointer and the function is inline you will need the full type. If you create a cpp file for the implementation you can avoid the circular dependecy (since neither of the class will need to include each others .h in their headers)
Something like this:
your header:
#ifndef GEMELEMENT_H_INCLUDED
#define GEMELEMENT_H_INCLUDED
class GemsGame;
class GemElement {
private:
GemsGame* _gemsGame;
public:
GemElement();
};
#endif // GEMELEMENT_H_INCLUDED
your cpp:
#include "GenGame.h"
GenElement::GenElement()
{
_gemsGame = application.getCurrentGame();
_gemsGame->getGemsVector();
}
Two ways out:
Keep the dependent classes in the same H-file
Turn dependency into abstract interfaces: GemElement implementing IGemElement and expecting for IGemsGame, and GemsGame implementing IGemsGame and containing a vector of IGemElement pointers.
Look at the top answer of this topic: When can I use a forward declaration?
He really explains everything you need to know about forward declarations and what you can and cannot do with classes that you forward declare.
It looks like you are using a forward declaration of a class and then trying to declare it as a member of a different class. This fails because using a forward declaration makes it an incomplete type.
I'm trying to refactor my code so that I use forward declarations instead of including lots of headers. I'm new to this and have a question regarding boost::shared_ptr.
Say I have the following interface:
#ifndef I_STARTER_H_
#define I_STARTER_H_
#include <boost/shared_ptr.hpp>
class IStarter
{
public:
virtual ~IStarter() {};
virtual operator()() = 0;
};
typedef boost::shared_ptr<IStarter> IStarterPtr;
#endif
I then have a function in another class which takes an IStarterPtr object as argument, say:
virtual void addStarter(IStarterPtr starter)
{
_starter = starter;
}
...
IStarterPtr _starter;
how do I forward declare IStarterPtr without including IStarter.h?
I'm using C++98 if that is of relevance.
Shared pointers work with forward declared types as long as you dont call * or -> on them so it should work to simply write :-
class IStarter;
typedef boost::shared_ptr<IStarter> IStarterPtr;
You need to include <boost/shared_ptr.hpp> of course
Though it would add a header file, you could put that in a separate header file :
#include <boost/shared_ptr.hpp>
class IStarter;
typedef boost::shared_ptr<IStarter> IStarterPtr;
and then include it both in IStarter.h and in your other header, avoiding code duplication (though it's quite small in this case).
There might be better solutions though.
You can't forward declare typedefs in C++98 so what I usually do in this case is pull out the typedefs I need an put them into a types.h file, or something similar. That way the common type code is still separated from the definition of the class itself.
There is a way but you need to include the boost header in your file :
#include <boost/shared_ptr.hpp>
class IStarter;
typedef boost::shared_ptr<IStarter> IStarterPtr;
// ...
virtual void addStarter(IStarterPtr starter)
{
_starter = starter;
}
// ...
IStarterPtr _starter;
It's my first code with classes. the dev c++ compiler find 4 errors so i need a help. I think there's something wrong in my concept may be
This was the Header file "complex.h"
class complex{
public:
bool ReadComplex();
private:
double real;
double imag;
};
This is the .cpp file
#include "complex.h"
#include <iostream.h>
#include <math.h>
using namespace std;
bool complex::ReadComplex()
{ cout<<"Enter the real part";
cin>>real;
cout<<"Enter the imaginary part";
cin>>imag;
return true;
}
and i got 4 errors
C:/Dev-Cpp/include/c++/3.4.2/mingw32/bits/c++config.h:57: error: expected unqualified-id before "namespace"
C:/Dev-Cpp/include/c++/3.4.2/mingw32/bits/c++config.h:57: error: expected ,' or;' before "namespace"
C:/Dev-Cpp/include/c++/3.4.2/mingw32/bits/c++config.h:61: error: expected namespace-name before ';' token
C:/Dev-Cpp/include/c++/3.4.2/mingw32/bits/c++config.h:61: error: `' is not a namespace
Thanks a lot,
class definition should end with a ;
class complex
{
// ....
} ;
//^ missing semi-colon
You forgot the semicolon at the end of the class definition:
class complex{
}; //<------- here put a semicolon
Make sure you put the class in your own named namespace, or else not say using namespace std. There's a std::complex type, and although you don't include its header, implementors are allowed to include it themselves in any of the standard headers.
End your class definition with a semicolon: class complex { /* ... */ };
Don't use <iostream.h>. Use <iostream>. Things there are in the std:: namespace, by the way.
What's <Math.h>? Is it some 3rd party library you're using that's installed outside your project tree? If it's your own code or inside your project tree then use double quotes, not angle brackets. Double quotes ask the compiler to search for the code in your tree, whereas angle brackets ask the compiler to look in system directories.
Are you sure the standard math header won't do? Take a look at the <cmath> header.
You should also
make GetReal() and GeatImag() const functions. If the Get or Set counterparts don't do anything special you should throw them away and set the member data public. This because less code is less bugs.
You should take parameters as const references whenever it makes sense. Like in complex::Add(), for example, which should be a const function too if it doesn't change the object.
Your first code with classes should be:
class complex{
};
int main()
{
return(0);
}
Seriously. Get this to work, with no compiler warnings. Then add complexity a little at a time, and never add to code that doesn't work.
this is my first question here.
Writing some code, i receive this error from g++: "Entity was not declared in this scope", in this context:
#ifndef Psyco2D_GameManager_
#define Psyco2D_GameManager_
#include <vector>
#include "Entity.h"
namespace Psyco2D{
class GameManager{J
private:
std::vector<Entity> entities;
};
}
#endif
This is the content of Entity.h:
#ifndef Psyco2D_Entity_
#define Psyco2D_Entity_
#include <string>
#include "GameManager.h"
#include "EntityComponent.h"
namespace Psyco2D{
class Entity{
friend class GameManager;
private:
/* Identificatore */
std::string _name;
/* Components list */
std::map<const std::string, EntityComponent*> components;
protected:
Entity(const std::string name);
public:
inline const std::string getName() const{
return this->_name;
}
void addComponent(EntityComponent* component, const std::string name);
EntityComponent* lookupComponent(const std::string name) const;
void deleteComponent(const std::string name);
};
}
#endif
If i use std::vector<class Entity> instead of std::vector<Entity> it works.
Why?
Thanks to all =)
The problem is you have a cyclic dependency. Take out #include "GameManager.h" in Entity.h, since you don't actually need it in that header. (Up-vote this answer, which first pointed it out.)
Note the guards are actually the problem; but don't take them out! You just need to minimize the includes you have, and declare (and not define) types when possible. Consider what happens when you include Entity.h: As some point it includes GameManager.h, which in turn includes Entity.h. At this point, Entity.h already has its header guard defined, so it skips the contents. Then the parsing of GameManager.h continues, where upon it runs into Entity, and rightfully complains it is not defined. (Indeed, this is still the process of including GameManager.h in the first inclusion of Entity.h, far before Entity is defined!)
Note your numerous edits demonstrate why it's important to post real code, not re-synthesized code. You need real details to get real answers.
Old:
Entity is in the Psyco2D namespace. You need to specify that:
class GameManager{
private:
std::vector<Psyco2D::Entity> entities;
};
Assuming the first snippet is part of GameManager.h you have a circular header dependency. I believe you can fix this by changing the GameManager.h include in Entity.h to class GameManager; instead.
Additionally as GMan noted, Entity is in a namespace and you need to qualify Entity with the namespace name.
Remove the Psyco2D-namespace and it will work without declaring "class Entity".