Reputation: 7304
I am confused how to implement data member access from a different class. I have three classes in three different header files.
A.h
#include "B.h"
#include "C.h"
class A{
B *b;
friend void dataaccess_b_from_class_A(int a);
}
B.h
class B{
}
C.h
class C{
void dataaccess_b_from_class_A(int a);
}
void C::dataaccess_b_from_class_A(int a)
{
b = new B(); //I got error as symbol b could not be resolved.
}
I like dataaccess_b_from_class_A()
method from class C
access data B *b
from Class A
.
I put friend function inside class A
, but I got error as symbol b could not be resolved
.How can I implement it?
EDIT1: According to the discussion 'gmas80', what I did was
class B; // forward declaration
class A{
public:
A(){};
private:
static B* b; // since in the dataaccess_to_class_A you are using new
friend class C; // this make b and dataaccess_from_class_C accessible
};
class B{
public:
B(){ cout << "B" << endl; };
// add content
};
class C{
public: // you need this keyword if you want to call this function from outside
void dataaccess_to_class_A(A a);
};
void C::dataaccess_to_class_A(A a)
{
A::b = new B(); //Error as undefined reference to class A::b
cout << "C" << endl; // test if called
}
If I don't include static, I got b could not be resolved
.
If I include static, I got undefined reference
.
Thanks
Upvotes: 0
Views: 64
Reputation: 1268
You have included so many mistakes in a so small piece of code! why don't you start simpler? Here a modified single-file version of your code that compiles:
#include <iostream>
using namespace std;
class B; // forward declaration
class A{
public:
A(){};
private:
B* b; // since in the dataaccess_to_class_A you are using new
void dataaccess_from_class_C(){ cout << "A" << endl; }; // test if called
friend class C; // this make b and dataaccess_from_class_C accessible
};
class B{
public:
B(){ cout << "B" << endl; };
// add content
};
class C{
public: // you need this keyword if you want to call this function from outside
void dataaccess_to_class_A(A a);
};
void C::dataaccess_to_class_A(A a)
{
a.b = new B(); // this is a potentially memory leak if you will not delete in somehow
a.dataaccess_from_class_C();
cout << "C" << endl; // test if called
}
// it is better if you post runnable code
int main() {
C c;
A a;
c.dataaccess_to_class_A(a);
}
AFTER EDIT1
Now you can start to move the class in a header file, but you need to add guardians to avoid multiple definitions..
a.h
#ifndef H_GUARDIAN_A
#define H_GUARDIAN_A
#include <iostream>
using namespace std;
class B; // forward declaration
class A
{
public:
A()
{};
private:
B* b; // since in the dataaccess_to_class_A you are using new
void dataaccess_from_class_C()
{
cout << "A" << endl;
}; // test if called
friend class C; // this make b and dataaccess_from_class_C accessible
};
class B
{
public:
B()
{
cout << "B" << endl;
};
// add content
};
class C
{
public: // you need this keyword if you want to call this function from outside
void dataaccess_to_class_A( A a );
};
void C::dataaccess_to_class_A( A a )
{
a.b = new B(); // this is a potentially memory leak if you will not delete in somehow
a.dataaccess_from_class_C();
cout << "C" << endl; // test if called
}
#endif
main.cpp
#include "a.h"
// it is better if you post runnable code
int main()
{
C c;
A a;
c.dataaccess_to_class_A( a );
}
Does it make sense for you? I simple moved the class declarations in another file that is included..
EDIT2
Now we split the class definitions in three different headers..
a.h
#ifndef H_GUARDIAN_A
#define H_GUARDIAN_A
#include <iostream>
using namespace std;
class B;
class A
{
public:
A(): b(NULL){}; // initialize to NULL the b pointer
~A(); // new entry: destructor to eventually delete b (only member function declaration)
private:
B* b; // since in the dataaccess_to_class_A you are using new
void dataaccess_from_class_C()
{
cout << "A" << endl; // test if called
};
friend class C; // this make b and dataaccess_from_class_C accessible
};
#endif
a.cpp // new entry! it avoids circular dependency.. the destructor is defined here
#include "a.h"
#include "b.h"
A::~A() // destructor that eventually clean memory for b
{
if( b ) delete b;
}
b.h
#ifndef H_GUARDIAN_B
#define H_GUARDIAN_B
#include "a.h"
class B
{
public:
B()
{
cout << "B" << endl;
};
// add content
};
#endif
c.h
#ifndef H_GUARDIAN_C
#define H_GUARDIAN_C
#include "b.h"
class C
{
public: // you need this keyword if you want to call this function from outside
void dataaccess_to_class_A( A a );
};
void C::dataaccess_to_class_A( A a )
{
a.b = new B(); // this is a potentially memory leak if you will not delete in somehow
a.dataaccess_from_class_C();
cout << "C" << endl; // test if called
}
#endif
main.cpp
#include "c.h"
// it is better if you post runnable code
int main()
{
C c;
A a;
c.dataaccess_to_class_A( a );
}
Upvotes: 1
Reputation: 723
add
include "B.h"
in the beginning if the C.h and define the type of b
B b( new B() );
also, specify the fully qualified method in your freind declaration:
friend void C::dataaccess_b_from_class_A(int a);
include C.h into A.h, and do not forget include guards in each header
Another point. Why are you defining C::dataaccess_b_from_class_A in the header? I would suggest to do it in a separate file. Say, "C.cpp".
Upvotes: 0