Is there a cyclic dependency here? - c++

Below I have reproduced a simplified version of a part of my code that gives error when compiling.
testing.cpp
#include <iostream>
#include "../Beta.h"
#include "../Alpha.h"
using namespace std;
int main() {
cout << "!!!Hello World!!!" << endl; // prints !!!Hello World!!!
return 0;
}
Alpha.h
#include <vector>
class Alpha
{
public:
typedef struct _info{
int k;
} info;
friend class Beta;
};
Beta.h
#include <vector>
class Alpha;
class Beta
{
public:
std::vector <Alpha::info*> vecInfo;
};
When I run g++ testing.cpp I get below error message
In file included from testing.cpp:10:0: ../Beta.h:8:15: error:
incomplete type ‘Alpha’ used in nested name specifier ../Beta.h:8:15:
error: incomplete type ‘Alpha’ used in nested name specifier
../Beta.h:8:27: error: template argument 1 is invalid ../Beta.h:8:27:
error: template argument 2 is invalid
I can see from the forum threads that the first error is because of some kind of cyclic dependency (Error: incomplete type used in nested name specifier). I am unable to see similarity between my code and their code. What am I doing wrong.

This is not really a circular dependency. Beta.h just needs to #include "Alpha.h" instead of forward-declaring class Alpha;.

You need to include Alpha.h in Beta.h, because the full class definition is needed to have access to Alpha::info. This will not create a cyclic dependency because Alpha.h does not include Beta.h.
// don't forget the include guards!
#ifndef BETA_H_
#define BETA_H_
#include <vector>
#include "../Alpha.h"
class Beta
{
public:
std::vector <Alpha::info*> vecInfo;
};
#endif

Related

C++ class in separate file not compiling. Already defined in Class.obj one or more multiply defined symbols found

So I've done extensive googling and searching on StackOverflow and am unable to find a solution despite several answers with this exact issue.
I am trying to create a test class in an external file called Fpc5.cpp
It's contents are:
Fpc5.cpp
#include "stdafx.h"
#include "Fpc5.h";
#include <iostream>
using std::cout;
class Fpc5 {
int bar;
public:
void testMethod();
};
void Fpc5::testMethod() {
cout << "Hey it worked! ";
}
and my main .cpp file:
Test.cpp
// Test.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "iostream"
//#include "Fpc5.cpp"
#include "Fpc5.h";
using std::cout;
using std::cin;
using std::endl;
int main()
{
cout << "Hello" << endl;
Fpc5 testObj;
testObj.testMethod();
system("pause");
return 0;
}
all the answers I've read indicate this is caused becaused I used to be including the class in the main file itself which is why I created a header file
Fpc5.h
#pragma once
void testMethod();
This changed the error, but still did not fix the issue. Currently my Test.cpp does not recognize a Fpc5 class. I've also tried adding the Fpc5.cpp and Fpc5.h in stdafx.h and that still does not resolve the issue.
stdafx.h
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#pragma once
#include "targetver.h"
#include <stdio.h>
#include <tchar.h>
// TODO: reference additional headers your program requires here
//#include "Fpc5.cpp"
#include "Fpc5.h"
I'm sure this a simple syntax/conceptual understanding error, but I'm quite new to c++ and am not sure what is wrong.
This is definition of your class and it must be in Fpc5.h
class Fpc5 {
int bar;
public:
void testMethod();
};
Then, you have Fpc5.cpp where you implement methods of the class:
#include "Fpc5.h" // Compiler needs class definition to compile this file!
void Fpc5::testMethod()
{
}
And then you can use Fpc5 class in Test.cpp
#include "Fpc5.h"
int main()
{
Fpc5 foo;
foo.testMethod();
return 0;
}
As an alternative you can pack everything into Test.cpp
Move the definition of your class:
class Fpc5 {
int bar;
public:
void testMethod();
};
to the header file, "Fpc5.h".
Implement the methods to "Fpc5.cpp".

Order of header file inclusions and dependencies

I'm just trying to test splitting code into multiple files.
I have:
//testMultiple.cpp
#include <string>
#include <iostream>
#include "testInclude.cpp"
int main(){
std::cout << "hi";
}
and
//testInclude.cpp
class testClass{
public:
string x;
};
This is giving testInclude.cpp:3:9: error: ‘string’ does not name a type
I thought since it was including before it included the testInclude.cpp, string would be defined for use in testInclude.cpp.
You need to use std::string instead of string.
You're including a cpp file, not a hpp file.
Common practice is to include header (h/hpp) files, not implementation (c/cpp) files.
If you only compile testMultiple.cpp, this should work. If the compiler is compiling testInclude.cpp separately, it will not see the `#include
Try renaming testInclude.cpp to testInclude.hpp and ensure it is not being compiled.
Here's an example:
///// testInclude.h
#include <vector>
class testClass{
public:
std::vector<int> x; // vector is in std namespace
};
///// testMultiple.cpp
// #include <vector> - gets this through testInclude.h
#include "testInclude.h"
int main(){
}
Use
class testClass{
public:
std::string x;
};

C++ Forward declaration and destructor

Two of my classes had to include each other. I made forward declarations instead, compilation is ok. One function of these classes is to call the destructor of the other. And that the compiler spits warnings at me, the destructor will not be called. What can I do? I can avoid this problem by creating another class for the function I need, avoiding the forward declarations but that would not be educative for me...
Here is my first class Header.h :
#ifndef H_HEADER
#define H_HEADER
#include "SDL/SDL.h"
#include "SDL/SDL_image.h"
#include "SDL/SDL_ttf.h"
#include <string>
#include <iostream>
#include <fstream>
#include <vector>
#include <sstream>
#include "DataFiles.h"
class Character; // forward declaration Header <-> Character
class Header {
private:
Character * ch;
};
void cleanUp(std::vector <SDL_Surface*> & Vsurface, std::vector <TTF_Font*> & Vfont, std::vector <Character*> & Vchar);
// ... Other functions use in main.cpp
#endif
HEre is the Header.cpp:
#include "Header.h"
using namespace std;
void cleanUp(vector <SDL_Surface*> & Vsurface, vector <TTF_Font*> & Vfont, vector <Character*> & Vchar) {
for(unsigned int i(0); i < Vsurface.size(); i++)
SDL_FreeSurface(Vsurface[i]);
for(unsigned int i(0); i < Vfont.size(); i++)
TTF_CloseFont(Vfont[i]);
for(unsigned int i(0); i < Vchar.size(); i++)
delete Vchar[i];
TTF_Quit();
SDL_Quit();
}
And here is the other Character.h class:
#ifndef H_CHARACTER
#define H_CHARACTER
#include <string>
#include <iostream>
#include <sstream>
#include <vector>
#include </usr/include/SDL/SDL_image.h>
#include </usr/include/SDL/SDL.h>
#include </usr/include/SDL/SDL_ttf.h>
#include "DataFiles.h"
#include "CharFrame.h"
class Header; // Forward declaration Header <-> Character
class Character {
public:
Character(std::string& dataPath);
~Character();
// .. other functions
private:
Header * h;
// ... other attributes
};
#endif
And here is my Character destructor:
Character::~Character() {
cout << "Character " << m_name << " deleted.\n-----------------------------------\n" << endl;
}
So when my program ends, I call upon the Header's function "cleanUp()" giving it a vector of pointers to Characters. Every pointer should then be deleted through the Character's destructor ~Character();
However compilation gives me three warnings:
Header.cpp: In function ‘void cleanUp(std::vector<SDL_Surface*>&, std::vector<_TTF_Font*>&, std::vector<Character*>&)’:
Header.cpp:66:17: warning: possible problem detected in invocation of delete operator: [enabled by default]
Header.cpp:66:17: warning: invalid use of incomplete type ‘struct Character’ [enabled by default]
Header.h:27:7: warning: forward declaration of ‘struct Character’ [enabled by default]
Header.cpp:66:17: note: neither the destructor nor the class-specific operator delete will be called, even if they are declared when the class is defined
And once my program terminates, the character's destructor's message won't show up which means the destructor clearly isn't called.
What am I doing wrong with the forward declarations?
Yep, that's what the (draft) standard says (§5.3.5.5);
If the object being deleted has incomplete class type at the point of deletion and the complete class has a
non-trivial destructor or a deallocation function, the behavior is undefined.
(a non trivial destructor being one you defined yourself)
To fix it, just #include "Character.h" in header.cpp before invoking delete to allow the type to be completely declared.
When you use class MyClass; to forward declare your class, this only declares that the thing with the name MyClass is a class, it does not declare the internal methods of the class.
Whenever you need to use one of the internal methods (such as a non-trivial destructor) you need to include the full declaration of the class (this means include the header file containing the class definition). Without this, the compiler has no way of knowing what the internal structure of your class actually looks like.
Here is an example:
// main.cpp
#include "head1.hpp" // An instance of Head1 is created in this file
#include "head2.hpp" // An instance of Head2 is created in this file
int main(int argc, char** argv)
{
Head1 head1(true);
Head2 head2(true);
return 0;
}
// head1.hpp
#ifndef HEAD1_HPP
#define HEAD1_HPP
class Head2; // A pointer to a class is declared, but no instance is created
// so here we only need a forward declaration
class Head1
{
public:
Head1(bool real=false);
~Head1();
private:
Head2* myHead2;
};
#endif /* #ifndef HEAD1_HPP */
// head2.hpp
#ifndef HEAD2_HPP
#define HEAD2_HPP
class Head1; // Same as above
class Head2
{
public:
Head2(bool real=false);
~Head2();
private:
Head1* myHead1;
};
#endif /* #ifndef HEAD2_HPP */
// head1.cpp
#include "head1.hpp" // Include the header we are defining methods for
#include "head2.hpp" // We also create an instance of Head2 in here
#include <iostream>
using namespace std;
Head1::Head1(bool real) {
myHead2 = real ? new Head2() : NULL;
cout << "Hello Head 1" << endl;
}
Head1::~Head1() {
cout << "Bye Head 1" << endl;
if (myHead2 != NULL) delete myHead2;
}
// head2.cpp
#include "head2.hpp" // As above
#include "head1.hpp"
#include <iostream>
using namespace std;
Head2::Head2(bool real) {
myHead1 = real ? new Head1() : NULL;
cout << "Hello Head 2" << endl;
}
Head2::~Head2() {
cout << "Bye Head 2" << endl;
if (myHead1 != NULL) delete myHead1;
}

G++ Error: In file included, then Foo was not declared

I have a problem with my C++ code. If I insert #include "god.hpp" in neuron.hpp, g++ shows me the following error:
In file included from neuron.hpp:4,
from main.cpp:5:
god.hpp:11: error: ‘Neuron’ has not been declared
god.hpp:13: error: ‘Neuron’ was not declared in this scope
god.hpp:13: error: template argument 1 is invalid
god.hpp:13: error: template argument 2 is invalid
main.cpp: In function ‘int main()’:
main.cpp:36: error: no matching function for call to ‘God::regNeuron(Neuron*&)’
god.hpp:11: note: candidates are: long int God::regNeuron(int*)
In file included from god.hpp:5,
from god.cpp:3:
neuron.hpp:10: error: ‘God’ has not been declared
In file included from neuron.hpp:4,
from neuron.cpp:2:
god.hpp:11: error: ‘Neuron’ has not been declared
god.hpp:13: error: ‘Neuron’ was not declared in this scope
god.hpp:13: error: template argument 1 is invalid
god.hpp:13: error: template argument 2 is invalid
and here are the related (parts) of the necessary files:
//main.cpp
#include <string>
#include <vector>
#include "functions.hpp"
#include "neuron.hpp"
#include "god.hpp"
using namespace std;
int main()
{
God * god = new God();
vector<string>::iterator it;
for(it = patterns.begin(); it != patterns.end(); ++it) {
Neuron * n = new Neuron();
god->regNeuron(n);
delete n;
cout << *it << "\n";
}
}
The God ;) Who will handle all neurons...
//god.hpp
#ifndef GOD_HPP
#define GOD_HPP 1
#include <vector>
#include "neuron.hpp"
class God
{
public:
God();
long regNeuron(Neuron * n);
private:
std::vector<Neuron*> neurons;
};
#endif
//god.cpp
#include <iostream>
#include <vector>
#include "god.hpp"
#include "neuron.hpp"
using namespace std;
God::God()
{
vector<Neuron*> neurons;
}
long God::regNeuron(Neuron * n)
{
neurons.push_back(n);
cout << neurons.size() << "\n";
return neurons.size();
}
And at least, my Neuron.
//neuron.hpp
#ifndef NEURON_HPP
#define NEURON_HPP 1
#include "god.hpp" //Evil
class Neuron
{
public:
Neuron();
void setGod(God *g);
};
#endif
//neuron.cpp
#include <iostream>
#include "neuron.hpp"
#include "god.hpp"
Neuron::Neuron()
{
}
void Neuron::setGod(God *g)
{
std::cout << "Created Neuron!";
}
I hope someone can help me to find the error. It happens when I write #include "god.hpp" in neuron.hpp. I searched around three hours with Google, but I had no luck.
Kind regards
-Boris
Compiled with:
g++ -Wall -o getneurons main.cpp functions.cpp god.cpp neuron.cpp
Remove
#include "god.hpp"
and replace it with a forward declaration:
//neuron.hpp
#ifndef NEURON_HPP
#define NEURON_HPP 1
class God; //forward declaration
class Neuron
{
public:
Neuron();
void setGod(God *g);
};
#endif
Same for God.hpp:
//god.hpp
#ifndef GOD_HPP
#define GOD_HPP 1
#include <vector>
class Neuron; //forward declaration
class God
{
public:
God();
long regNeuron(Neuron * n);
private:
std::vector<Neuron*> neurons;
};
#endif
Note that you'll need the includes in your implementation files. (cpp files)
If you use pointers or references to objects as members or use that type as a return type or parameter, the full definition isn't required, so a forward declaration is enough.

hello to boost multi index

I have started working on a project that incorporates some of boost libraries(thread and MPI).
I am going to use boost multi_index in one of the modules which is not using boost at all.FYI this project has not used boost multi index before)
as soon as I tried to include
boost/multi_index_container.hpp
to the file and built the projects, I received a number of errors starting with the following:
Building CXX object CMakeFiles/SimMobility.dir/main.cpp.o
/usr/bin/c++ -fmessage-length=0 -DBOOST_NO_HASH -O0 -g -I/usr/include/postgresql -I/usr/include/soci -I/usr/include/soci/postgresql -I/usr/include/xsd -I/home/vahid/workspace/Basic__Multi_index -o CMakeFiles/SimMobility.dir/main.cpp.o -c /home/vahid/workspace/Basic__Multi_index/main.cpp
In file included from /usr/include/boost/multi_index/detail/node_type.hpp:22:0,
from /usr/include/boost/multi_index/detail/index_base.hpp:21,
from /usr/include/boost/multi_index/detail/base_type.hpp:21,
from /usr/include/boost/multi_index_container.hpp:33,
from /home/vahid/workspace/Basic__Multi_index/geospatial/RoadNetwork.hpp:10,
from /home/vahid/workspace/Basic__Multi_index/main.cpp:25:
/usr/include/boost/multi_index/detail/header_holder.hpp:41:16: error: expected unqualified-id before ‘)’ token
/usr/include/boost/multi_index/detail/header_holder.hpp: In constructor ‘boost::multi_index::detail::header_holder<NodeTypePtr, Final>::header_holder()’:
/usr/include/boost/multi_index/detail/header_holder.hpp:35:32: error: expected primary-expression before ‘)’ token
may I know what the problem is? is it cmake not finding what it needs? any idea how to solve it?
Edit:
in case you want to have a look at the source code, here is a simplified version:
RoadNetwork.hpp:
#pragma once
#include <iostream>
#include <vector>
#include <set>
#include <boost/multi_index_container.hpp> //causing problem!!!!!!!
namespace geo {class Links_pimpl;}
namespace sim_mob
{
//Forward declarations
class Node;
class UniNode;
class MultiNode;
class Point2D;
class Link;
namespace aimsun
{
//Forward declaration
class Loader;
}
//typedef multi_index_container<
//sim_mob::Link,
// indexed_by<
// random_access<>,
//// ordered_unique< member<sim_mob::Link, std::string, &sim_mob::Link::linkID> >
// >
//> Link_m;
class RoadNetwork {
public:
RoadNetwork() { drivingSide=DRIVES_ON_LEFT; } //TEMP
sim_mob::Node* locateNode(const sim_mob::Point2D& position, bool includeUniNodes=false, int maxDistCM=100) const;
private:
std::vector<sim_mob::MultiNode*> nodes;
std::vector<sim_mob::Link*> links;
std::vector<sim_mob::MultiNode*>& getNodesRW() { return nodes; }
std::set<sim_mob::UniNode*>& getUniNodesRW() { return segmentnodes; }
std::vector<sim_mob::Link*>& getLinksRW() { return links; }
friend class sim_mob::aimsun::Loader;
friend class geo::Links_pimpl;
};
}
Thank you your kind help
vahid
I modified your header to look like this:
#pragma once
#include <iostream>
#include <vector>
#include <set>
#include <boost/multi_index_container.hpp> //causing problem!!!!!!!
using boost::multi_index_container;
namespace geo {class Links_pimpl;}
namespace sim_mob
{
//Forward declarations
class Node;
class UniNode;
class MultiNode;
class Point2D;
class Link;
namespace aimsun
{
//Forward declaration
class Loader;
}
//typedef multi_index_container<
//sim_mob::Link,
// indexed_by<
// random_access<>,
// ordered_unique< member<sim_mob::Link, std::string, &sim_mob::Link::linkID> >
// >
//> Link_m;
class RoadNetwork {
int drivingSide;
enum side { DRIVES_ON_LEFT, DRIVES_ON_RIGHT};
public:
RoadNetwork() { drivingSide=DRIVES_ON_LEFT; } //TEMP
sim_mob::Node* locateNode(const sim_mob::Point2D& position, bool includeUniNodes=false, int maxDistCM=100) const;
private:
std::vector<sim_mob::MultiNode*> nodes;
std::vector<sim_mob::Link*> links;
std::set<sim_mob::UniNode*> segmentnodes;
std::vector<sim_mob::MultiNode*>& getNodesRW() { return nodes; }
std::set<sim_mob::UniNode*>& getUniNodesRW() { return segmentnodes; }
std::vector<sim_mob::Link*>& getLinksRW() { return links; }
friend class sim_mob::aimsun::Loader;
friend class geo::Links_pimpl;
};
}
Then I included it in a small file that instantiated a RoadNetwork object:
#include <iostream>
#include "roadnetwork.hpp"
int main() {
sim_mob::RoadNetwork roads;
return 0;
}
This compiled, linked, and executed (though produced no output).
Not entirely sure what problem you're encountering...
I encountered the same problem and tracked it down. Do you have by chance a #define final somewhere in your sources before including boost/multi_index.hpp or a -Dfinal in your compiler settings? In my case that was the problem, I use the C++11 keywords final and override in my classes and had to define them when using older compilers.
Or, maybe it's some other identifier used by multi_index that you have defined somewhere. You could dump all your defined macros as described here and check if disabling one of them helps.
I also encountered similar problem.
I got compile error in
multi_index header_holder file.
warning : final key word is blah... blah...
So I changed the
#include <boost/xxxxx>
position to other place.
( ex: stdafx.h etc ... )
Try this one.