I have a strange problem when I create a static function in class A and I want to call it from class B function. I get
undefined reference to `A::funcA(int)'
Here is my source code :
a.cpp
#include "a.h"
void funcA(int i) {
std::cout << i << std::endl;
}
a.h
#ifndef A_H
#define A_H
#include <iostream>
class A
{
public:
A();
static void funcA( int i );
};
#endif // A_H
b.cpp
#include "b.h"
void B::funcB(){
A::funcA(5);
}
and b.h
#ifndef B_H
#define B_H
#include "a.h"
class B
{
public:
B();
void funcB();
};
#endif // B_H
I'm compiling with Code::Blocks.
#include "a.h"
void funcA(int i) {
std::cout << i << std::endl;
}
should be
#include "a.h"
void A::funcA(int i) {
std::cout << i << std::endl;
}
Since funcA is a static function of your class A. This rule applies both to static and non-static methods.
You forgot to prefix the definition with the class name :
#include "a.h"
void A::funcA(int i) {
^^^
//Add the class name before the function name
std::cout << i << std::endl;
}
The way you did things, you defined an unrelated funcA(), ending up with two functions (namely A::funcA() and funcA(), the former being undefined).
Related
Is it possible to avoid circular dependency in the following header files without turning data member b1 in class A to a pointer/reference, and without relaxing the inline function requirement in class B?
A.h:
#ifndef A_H
#define A_H
#include <B.h> // Required, as data member b1 is not a pointer/reference
class A {
public:
B b1; // I want to keep this as as it is.
int m_a;
};
#endif
B.h:
#ifndef B_H
#define B_H
#include <A.h> // Required, as f() calls a member function of class A
class B {
public:
int f(A &a){return a.m_a;} // I want this to be an inline function.
};
#endif
...and let's say main.ccp is:
#include <iostream>
#include <A.h>
#include <B.h>
int main() {
A a;
B b;
std::cout << "Calling b.f(a): " << b.f(a) << std::endl;
return 0;
}
You could use this:
A.h
#include <B.h>
#ifndef A_H
#define A_H
class A
{
public:
B b1;
int m_a;
};
#endif // A_H
B.h
#ifndef B_H
#define B_H
class A;
class B
{
public:
int f(A &a);
};
#include <A.h>
inline int B::f(A &a)
{
return a.m_a;
}
#endif // B_H
main.cpp
#include <iostream>
#include <A.h> // these could be in any order
#include <B.h>
int main()
{
A a;
B b;
std::cout << "Calling b.f(a): " << b.f(a) << std::endl;
return 0;
}
I want to inline my two structures. But they have pointer of each other. Like the code below:
A.h
#ifndef A_H
#define A_H
#include "b.h"
struct A
{
B* b;
int value;
A();
void Inc();
};
#endif // A_H
A.cpp
#include "a.h"
A::A()
{
b = new B(this);
}
void A::Inc()
{
b->value++;
}
B.h
#ifndef B_H
#define B_H
struct A;
struct B
{
A* a;
int value;
B(A* a);
void Inc();
};
#endif // B_H
B.cpp
#include "b.h"
#include "a.h"
B::B(A *a)
{
this->a = a;
}
void B::Inc()
{
a->value++;
}
main.cpp
#include <iostream>
#include <a.h>
using namespace std;
int main()
{
A a;
a.value = 0;
a.b->value = 0;
a.Inc();
a.b->Inc();
cout << a.value << endl;
cout << a.b->value << endl;
return 0;
}
I can not use keyword inline anywhere because it gives me the error undefined reference to methods.
Based on here, I can define my methods in header files but that would force me to use #include <a.h> inside the file b.h. But that would give me another error because of duplicate includes.
Now How can I inline both Inc methods?
It's not possible to inline all member functions of two mutually dependent structs in the body of the struct definition. It's possible to inline all the member functions by defining the functions outside the body of the struct definition and using the inline keyword explicitly. However, if you use two .h files to define the struct/classs, it becomes messy.
Here are some options to implement the member functions.
Option 1
Use only forward declarations in the .h files. Implement all the functions in the .cpp files. None of the member functions are inlined.
Option 2
Use forward declaration of A in B.h but use full definition of B in A.
In this case, all member functions of A can be inlined but member functions of B cannot be inlined. They will need to be implemented in a .cpp file.
Option 3
Reverse the roles of A and B from Option 2
Use forward declaration of B in A.h but use full definition of A in B.
In this case, all member functions of B can be inlined but member functions of A cannot be inlined. They will need to be implemented in a .cpp file.
a.h and b.h stay the same, a.cpp and b.cpp are merged into ab_inl.hpp containing the methods and constructors with an inline decorator** (or you can let the constructors be in their respective .cpp file) and the main.cpp (or any other file which needs it) includes ab_inl.hpp.
** as the compiler is free to ignore the inline qualifier, I preferred the term "decorator"
Everything below + a.h + b.h compiles just dandy:
File ab_inl.hpp:
#ifndef _AB_INL
#define _AB_INL
#include "a.h"
// included by a.h anyway
// #include "b.h"
inline A::A() : b(0), value(0)
{
b = new B(this);
}
inline void A::Inc()
{
b->value++;
}
inline B::B(A *a) : a(0), value(0)
{
this->a = a;
}
inline void B::Inc()
{
a->value++;
}
#endif // _AB_INL
File main.cpp
#include "ab_inl.hpp"
int main()
{
using std::cout;
using std::endl;
A a;
a.value = 0;
a.b->value = 0;
a.Inc();
a.b->Inc();
cout << a.value << endl;
cout << a.b->value << endl;
return 0;
}
When I build and run this code in Eclipse CDT, I expect it to print 1. It prints -1992206527 instead. Why is this?
Here's my code.
A.h
#ifndef A_H
#define A_H
class A {
private:
int a;
public:
A();
~A();
void printNum();
};
#endif
A.cpp
#include <iostream>
#include "A.h"
A::A() :
a(1)
{
}
A::~A(){}
void A::printNum(){
std::cout << a << std::endl;
}
B.h
#ifndef B_H_
#define B_H_
class A;
class B {
private:
A* obj;
public:
B();
~B();
int run();
};
#endif
B.cpp
#include "A.h"
#include "B.h"
B::B() {}
B::~B() {}
int B::run(){
obj->printNum();
return 0;
}
main.cpp
#include "B.h"
int main(int argc, char **argv) {
B b;
return b.run();
}
To make it print 1, you must initialize B::obj. Below is a B.cpp with obj being properly initialized/ deallocated.
#include "A.h"
#include "B.h"
B::B() : obj(new A) {}
B::~B() { delete obj;}
int B::run(){
obj->printNum();
return 0;
}
Alternatively, you could make obj be an object type A(i.e declare obj as A obj;), instead of making it a pointer to an object of type A. This would necessitate including A.hin B.h.
Is it possible to avoid circular dependency in the following header files without turning data member b1 in class A to a pointer/reference, and without relaxing the inline function requirement in class B?
A.h:
#ifndef A_H
#define A_H
#include <B.h> // Required, as data member b1 is not a pointer/reference
class A {
public:
B b1; // I want to keep this as as it is.
int m_a;
};
#endif
B.h:
#ifndef B_H
#define B_H
#include <A.h> // Required, as f() calls a member function of class A
class B {
public:
int f(A &a){return a.m_a;} // I want this to be an inline function.
};
#endif
...and let's say main.ccp is:
#include <iostream>
#include <A.h>
#include <B.h>
int main() {
A a;
B b;
std::cout << "Calling b.f(a): " << b.f(a) << std::endl;
return 0;
}
You could use this:
A.h
#include <B.h>
#ifndef A_H
#define A_H
class A
{
public:
B b1;
int m_a;
};
#endif // A_H
B.h
#ifndef B_H
#define B_H
class A;
class B
{
public:
int f(A &a);
};
#include <A.h>
inline int B::f(A &a)
{
return a.m_a;
}
#endif // B_H
main.cpp
#include <iostream>
#include <A.h> // these could be in any order
#include <B.h>
int main()
{
A a;
B b;
std::cout << "Calling b.f(a): " << b.f(a) << std::endl;
return 0;
}
My code looks something like this:
main.cpp
#include <iostream>
#include "A.h"
#include "B.h"
using namespace std;
int main(){
int d,f;
A c();
d = c.GetStuff();
B *d = new C();
f = d->Get();
return 0;
}
A.h
#ifndef A_H
#define A_H
class A
{
int a;
public A();
int GetStuff() {return(a) ;}
};
#endif
A.cpp
#include "A.h"
A::A()
{
a = 42;//just some value for sake of illustration
}
B.h
#ifndef B_H
#define B_H
Class B
{
public:
virtual int Get(void) =0;
};
class C: public B {
public:
C();
int Get(void) {return(a);}
};
#endif
B.cpp
#include "B.h"
C::C() {
a // want to access this int a that occurs in A.cpp
}
My question is, what is the best way to gain access to "a" in B.cpp?
I tried using class "friend", but I am not getting results.
Any suggestions?
Thanks!
Two different answers, depending on what you mean
If each A object is meant to have it's own unique 'a' variable (which is how you've defined it) then you'll need to pass an A into the constructor of C:
C::C(const A &anA) {
int foo= anA.a; //
}
And, invoking the constructor becomes:
A myA;
B *myC = new C(myA); // You picked confusing names for your classes and objects
However, if you intended all A objects to share a common a value, then you should declare a and getStuff as static in A :
class A
{
static int a;
public:
static int GetStuff() {return a;};
... and access it as A::GetStuff() in the C constructor.