"Exchange" of includes - c++

As you can see, the title is a little nonsense, it's because I really don't know how to call that, but know that I tried hard to find a better title.
I hope you understand what I'm trying to say seeing the rest of the question.
Let's suppose that I have 3 classes, "A", "B", and "C".
The class "A" includes "B" and "C".
The class "B" includes "A"
The class "C" includes "A"
Let's go the code...
#include <iostream>
#include <b.hpp>
#include <c.hpp>
class A
{
public:
A()
{
std::cout << "Hello from A" << std::endl;
A a;
B b;
}
};
#include <iostream>
#include <a.hpp>
class B
{
public:
B()
{
std::cout << "Hello from B" << std::endl;
}
};
#include <iostream>
#include <a.hpp>
class C
{
public:
C()
{
std::cout << "Hello from C" << std::endl;
}
};
This way, everything works fine, the output:
Hello from A
Hello from B
Hello from C
BUT, if I do that:
#include <iostream>
#include <a.hpp>
#include <vector>
class B
{
public:
B()
{
std::cout << "Hello from B" << std::endl;
}
private:
std::vector<A> garage;
};
I got a cascade of errors, including this one (actually, the main one, because of that one, there are others):
error: 'A' was not declared in this scope
std::vector garage;
This is exactly what I want, do you have an idea what I can do? Thank you.
#edit - As answer to #Kerrek SB
I tried to create separated files to each one, header and sources. (.hpp and .cpp) and the error persist.
A.hpp
#ifndef A_HPP
#define A_HPP
#include <iostream>
#include <B.hpp>
#include <C.hpp>
class A
{
public:
A();
};
#endif
A.cpp
#include <A.hpp>
A::A()
{
std::cout << "Hello from A" << std::endl;
B b;
C c;
}
B.hpp
#ifndef B_HPP
#define B_HPP
#include <iostream>
#include <A.hpp>
#include <vector>
class B
{
public:
B();
private:
std::vector<A> garage;
};
#endif
B.cpp
#include <B.hpp>
B::B()
{
std::cout << "Hello from B" << std::endl;
}
C.hpp
#ifndef C_HPP
#define C_HPP
#include <iostream>
#include <A.hpp>
class C
{
public:
C();
};
#endif
C.cpp
#include <C.hpp>
C::C()
{
std::cout << "Hello from C" << std::endl;
}
main.cpp
#include <iostream>
#include <A.hpp>
int main(int argc, char ** argv)
{
A a;
return 0;
}
gcc
g++ -O2 -std=c++11 -I"." -o exchange A.cpp B.cpp C.cpp main.cpp
output
In file included from ./A.hpp:5:0,
from ./C.hpp:5,
from C.cpp:1:
./B.hpp:13:17: error: 'A' was not declared in this scope
std::vector<A> garage;

Separate the class definitions from the class member definitions:
#include <iostream>
#include <vector>
class A { public: A(); };
class B { public: B(); private: std::vector<A> garage; };
class C { public: C(); };
A::A()
{
std::cout << "Hello from A" << std::endl;
// A a; // no, because that's idiotic
B b;
}
B::B()
{
std::cout << "Hello from B" << std::endl;
}
C::C()
{
std::cout << "Hello from C" << std::endl;
}
In a larger project, you would probably have separate header and source files for each of those.

Related

Simple Class and Header in Separate File Won't Work

I'm currently learning c++ for a week and here's my problem:
run.cpp
#include <iostream>
#include "Abc.h"
int main(){
int a;
std::cout << "Enter a : ";
std::cin >> a;
// Object Initialization
Abc AbcObj();
}
the header, Abc.h :
#ifndef ABC_H
#define ABC_H
class Abc
{
public:
Abc();
protected:
private:
};
#endif // ABC_H
and finally my cpp file for implementation, Abc.cpp:
#include "Abc.h"
#include <iostream>
Abc::Abc()
{
std::cout << std::endl << "Object created ";
}
Why don't I get output on my console? I'm expecting "object created" should be on the console. These files are in the same directory.
You error doesn't come up because you've used different files, so I have used one in this example
struct Foo
{
int a;
Foo()
{
std::cout << "Constructor called!";
}
};
int main()
{
Foo obj();
}
Why don't you see the message? You can read this thread
The problem here is, Foo obj() is taken as a function declaration. To fix this you need to remove the ()
int main()
{
Foo obj;
}
Constructor called!

c++ extern class does not name a type

I'm trying to declare a class object as extern but am getting the below error:
g++ a1.cpp -std=c++11
In file included from b1.h:5:0,
from a1.cpp:2:
c1.h:6:8: error: ‘b1’ does not name a type
extern b1 obj_b1;
^
I have looked in
Issue declaring extern class object
and
'[Class name]' does not name a type in C++
and I THINK I am following the steps mentioned there. But couldn't find what's the issue.
Files are :
a1.cpp
#include<iostream>
#include "b1.h"
b1 obj_b1;
int main(){
//access object from class B
std::cout << " test " << std::endl;
std::cout << " obj_b1 value is " << obj_b1.value << std::endl;
obj_b1.value = 6;
return 0;
}
b1.h
#ifndef CLASS_B1
#define CLASS_B1
#include "c1.h"
class b1{
public:
int value=5;
int print_value();
};
#endif
b1.cpp
#include <iostream>
#include "b1.h"
int b1::print_value(){
std::cout << "value in b1 is " << value << std::endl;
}
c1.h
#ifndef CLASS_C1
#define CLASS_C1
#include "b1.h" // this is an attempt to fix issue, but didnt work
extern b1 obj_b1; // Is there a better place to declare this ?
class c1 {
private:
int c1_value=10;
int c1_print_value();
};
#endif
c1.cpp
#include<iostream>
#include "c1.h"
int c1::c1_print_value()
{
std::cout << "in c1 , value is " << c1_value << std::endl;
std::cout << " obj_b1.value is " << obj_b1.value << std::endl;
return 0;
}
I can not understand why the compiler complains about b1, when I have added b1.h just above the extern declaration. Can someone help to solve the issue ?
b1.h includes c1.h, and c1.h includes b1.h. This is is a mess. By using the #indef/#define combo, you have prevented an infinite recursion, but it is still a mess.
obj_b1 doesn't have anything to do with class c1, so remove extern b1 obj_b1; from c1.h.
Now c1.h doesn't depend on anything in b1.h, so you can remove #include "b1.h" from c1.h.
An for similar reason, you should remove #include "c2.h" from b1.h.
On the other hand c2.cpp does depend on obj_b1 (assuming obj1.name is a typo, and should be obj_b1.name), so you should put extern b1 obj_b1; in b1.h and #include "b1.h" in c2.cpp.
For some extra cleanup, move b1 obj_b1; from a1.cpp to b1.cpp

Issue with circular dependency even after separating definitions [duplicate]

This question already has answers here:
Resolve build errors due to circular dependency amongst classes
(12 answers)
Closed 7 years ago.
Please see my previous post here:
Undefined type error even with forward declaration
I moved the definitions to cpp files and I still face the issue. Any ideas why? My files look like this:
Header1.hpp
#ifndef HEADER1_HPP
#define HEADER1_HPP
namespace sample_ns
{
class sample_class{
public:
static int getNumber();
static void print();
};
}
#endif
Header2.hpp
#ifndef HEADER2_HPP
#define HEADER2_HPP
namespace sample_ns
{
class sample_class2{
public:
sample_class2();
int getNumber2();
};
}
#endif
Source1.cpp
#include "Header1.hpp"
#include "Header2.hpp"
#include "stdafx.h"
#include <iostream>
namespace sample_ns
{
int sample_class::getNumber()
{
sample_class2 obj;
return obj.getNumber2();
}
void sample_class::print()
{
std::cout << "Print utility function" << std::endl;
}
}
Source2.cpp
#include "Header2.hpp"
#include "Header1.hpp"
#include "stdafx.h"
#include <iostream>
namespace sample_ns
{
sample_class2::sample_class2()
{
sample_class::print();
}
int sample_class2::getNumber2()
{
sample_class::print();
return 5;
}
}
In my main I call it as:
std::cout << sample_ns::sample_class::getNumber() << std::endl;
I get 'sample_class2' : undeclared identifier. I tried adding class sample_class2; but that still gives me error
EDIT:
my main file:
#include "stdafx.h"
#include <iostream>
#include "Header1.hpp"
int _tmain(int argc, _TCHAR* argv[])
{
std::cout << "hello" << std::endl;
std::cout << sample_ns::sample_class::getNumber() << std::endl;
return 0;
}
The best practice for declaring classes and namespaces in header and cpp files is using structure likes below:
Header1.hpp
#ifndef HEADER1_HPP
#define HEADER1_HPP
#include "Header2.hpp"
#include <iostream>
namespace sample_ns
{
class sample_class{
public:
static int getNumber();
static void print();
};
}
#endif
Source1.cpp
#include "Header1.hpp"
namespace sample_ns
{
int sample_class::getNumber()
{
sample_class2 obj;
return obj.getNumber2();
}
void sample_class::print()
{
std::cout << "Print utility function" << std::endl;
}
}
So by including in header files and using ifndef you become sure that circular dependencies will not occure.

How do I declare a const in a header?

I want to test defining a const in a header and use it in functions, then call it. However I get the error, I added include guards which doesn't help. Error is: LNK1169: One or more defined multiply symbols found. How can i do it in a nother way? Is declaring const in .h and defining this const in .cpp and then including this .cpp in all other .cpps the only solution?
Header
#ifndef STORY
#define STORY
const int x = 4;
#endif
.cpp
#include <iostream>
#include "8-04.h"
void func1()
{
int w = x;
std::cout << "func1 " << w << std::endl;
}
.cpp
#include <iostream>
#include "8-04.h"
void func2()
{
int z = x;
std::cout << "func2 " << z << std::endl;
}
main
#include <iostream>
#include "8-04.h"
#include "8-04first.cpp"
#include "8-04second.cpp"
using namespace std;
int main()
{
func1();
func2();
}
The problem is that each .cpp includes the .h. This means that each .o contains a const int x. When the linker links these together, you get multiple definitions.
The solution is to modify the .h
#ifndef STORY
#define STORY
extern const int x; //Do not initialise
#endif
and in a single .cpp:
const int x=4
Edit:
I didnt even see the #include <file.cpp> business. Don't do that. Its horrible.
This should be like :
header.h:
#ifndef STORY
#define STORY
const int x = 4;
void func1();
void func2();
#endif
fun1.cpp
#include <iostream>
#include "header.h"
void func1()
{
int w = x;
std::cout << "func1 " << w << std::endl;
}
fun2.cpp
#include <iostream>
#include "header.h"
void func2()
{
int z = x;
std::cout << "func2 " << z << std::endl;
}
main.cpp
#include <iostream>
#include "header.h"
using namespace std;
int main()
{
func1();
func2();
}
You can not include ".cpp"
It can be done such as :
header.h:
#ifndef STORY
#define STORY
const int x = 4;
void func1();
void func2();
#endif
fun1.cpp
#include <iostream>
#include "header.h"
using namespace std;
void func1()
{
int w = x;
cout << "func1 value of w = " << w << "\n";
}
fun2.cpp
#include <iostream>
#include "header.h"
using namespace std;
void func2()
{
int z = x;
cout << "func2 value of z = " << z << "\n";
}
main.cpp
#include <iostream>
#include "header.h"
int main()
{
func1();
func2();
}
".cpp" file cannot be included in main source file.

Classes not accessing global objects

This is really puzzling me. For some reason I get a
"c1 not declared in this scope"
error from the compiler. I am usig Mingw with Code::Blocks. I would assume global variables are global to the program? Am I wrong? TYIA -Roland
// main.h
#include <iostream>
#include "classone.cpp"
#include "classtwo.cpp"
extern AnotherClass c2;
extern TheClass c1;
----------
// main.cpp
#include "main.h"
AnotherClass c2;
TheClass c1;
int main()
{
c1.function5();
c2.function2();
return 0;
}
----------
//classone.h
#include "main.h"
class AnotherClass {
`
public:
void function2();
void function3();
private:
int varone;
int vartwo;
};
----------
// classone.cpp
#include "classone.h"
void AnotherClass::function2() {
std::cout << "Function 2 Check\n";
}
void AnotherClass::function3() {
std::cout << "Function 3 Check";
}
----------
// classtwo.h
#include "main.h"
class TheClass {
public:
void function4();
void function5();
};
----------
// classtwo.cpp
#include "classtwo.h"
void TheClass::function4() {
c1.function2();
std::cout << "Function 2 Check\n";
}
void TheClass::function5() {
std::cout << "Function 3 Check";
}
It's quite silly to include .cpp files like that - only include headers.
Anyway, change main.h to this:
#include <iostream>
extern AnotherClass c2;
extern TheClass c1;
Add this to main.cpp:
AnotherClass c2;
TheClass c1;
Then include main.h in each file which needs it, like this:
// classtwo.cpp
#include "classtwo.h"
#include "main.h"
void TheClass::function4() {
c1.function2();
std::cout << "Function 2 Check\n";
}
void TheClass::function5() {
std::cout << "Function 3 Check";
}
Also, you need include guards if you don't have those already.
You need to include the class declarations in your .cpp files if you want to compile all the code in a single file. Inside classtwo.cpp insert #include "classtwo.h" and do the same for classone at the top of both files.
Standard practice is to separate the class code from the client code, so you should compile the classes into a library and link it to the main program.
Your main .h needs to include the .h files of the 2 classes, for it to work. You do not (and should not ) need to include the .cpp files.