I have 4 classes.
class A, class B, class C, class D
Class C includes class A and class B and reference them:
The Header File:
class C
{
private:
A &a;
B &b;
int x;
int y;
int energy;
public:
C(A &a, B &b);
void print(void);
virtual void printAt(void);
CPP File includes:
void C::printAt(void)
{
// move cursor to the current x, y coordinates
b.gotoXY(x,y);
}
In class D, I make class C a friend class by (class D : public class C...)
Then I have a void printAt(void).
This all works, but how do I access the b class attributes (b.gotoXY..) from class D?
Hopefully this makes Sence.
Just put them in protected section:
class C {
protected:
A &a;
B &b;
...
};
NOTE: It has nothing to do with virtual methods.
The reason you cannot access them from D is because they are private, which means they are only accessible from within D itself. In order to be able to access them only from D or its subclasses, you need to use the protected access modifier instead:
class C
{
private:
int x;
int y;
int energy;
protected:
A &a;
B &b;
public:
C(A &a, B &b);
void print(void);
virtual void printAt(void);
/// ...
};
Now, a bit of terminology:
When you type class C : public D you are not making it a friend, you are inheriting from it. This means C will be a base class of D. A friend is another, related concept.
A friend of some class is another class which has access to its private properties. So, if you instead had made D a friend of C, you would have had access to a and b without having to make them protected. This would be accomplished as such:
class C
{
// Some code...
friend D;
//Lots of code ...
}
Please note that, for this to work, you need to declare D before C.
Now, which of these options should you use?
Ask yourself this question: is a D logically a more specific type of C? If so, it should use inheritance. If not, it may be better to make D have a member of type C and use the friend keyword. In either case, use friend sparingly, and only if there is necessarily a very tight relationship between the two classes (perhaps if D is a factory for type C and C has a private constructor.)
You should make intended members protected or make their classes friend to your class.
In addition, I feel you will have a problem when you instantiating an object from C because of uninitialized references.
class C
{
private:
A &a;
B &b;
// ...
public:
C(A &a, B &b) : a(a), b(b)
^^^^^^^^^^^^
// ...
};
when you want other class in inherit access to your attributes .dont private them
so you can choose protected or public.
for more detail you can go http://www.learncpp.com/cpp-tutorial/115-inheritance-and-access-specifiers/
for solve problem try below code
class C
{
protected://or public
A &a;
B &b;
int x;
int y;
int energy;
public:
C(A &a, B &b);
void print(void);
virtual void printAt(void);
and in class D
class D:public C
{
public:
void printAt(void);
};
Related
There are three classes, A, B, C;
Class A is friends with B, B has a protected data member. Class C inherits publicly from Class A. Can I access those protected data members of B by initializing a B object in a function of C?
If not how would I Go about accessing the values of B in C functions?
You cannot access the protected members of B directly in C but you could introduce a protected method in A that gets/sets the protected member in B; since C is derived from A you could access the protected get/set methods in A from C, see example below. Probably best to think about the overall design though.
class A
{
protected:
int getValueOfB(B& b) { return b.protectedValue; }
void setValueInB(B& b, int value) { b.protectedValue = value; }
};
class C
{
void doSomething()
{
B b;
setValueInB(b, 1);
}
}
friend are NOT inherited.
In the same way friend of friend are NOT friend.
As alternative, passkey idiom might help in your case:
class B;
class A
{
public:
struct Key{
friend class B; // no longer in class A.
private:
Key() = default;
Key(const Key&) = default;
};
// ...
};
class C : public A
{
private:
void secret(Key /*, ...*/) { /*..*/ }
};
class B
{
public:
void foo(C& c) {
c.secret(A::Key{}); // Access C private thanks to "private" key from A.
}
};
Sorry for the bad title... I think the solution may exist on this site, but I cannot find it.
class A {
};
class B {
private:
int _b;
};
class C {
private:
A a; // a: I want to access _b in b
B b;
};
Let's say I have 3 classes like the code above, now the object a in class C wants to access the member _b in object b. Is there any method to achieve it?
I tried using friend, I wonder if I haven't used it in a proper way, because it made the code very complex, like this:
class B {
private:
int _b;
public:
B() : _b(5) {}
int get_b() {
return _b;
}
};
class A {
public:
int get_a(B& b) {
cout << b.get_b();
}
};
class C {
private:
friend class A;
A a;
B b;
public:
A& get_A() {
return a;
}
B& get_B() {
return b;
}
};
int main() {
C c;
c.get_A().get_a(c.get_B());
}
Thank you in advance.
EDIT
Sorry about the confusing code above, actually I want to implement a compiler using OO style. I think a compiler is made of lexer, parser, and symbol table and other things. So I think the relationship is:
class compiler {
private:
lexer l;
parser p;
symbol_table st;
...
};
And the parser and lexer need to access the symbol_table, that is why this question is put forward. I think this design is resemble to the real compiler "in my opinion", but it seems hard to implement... Any advice is appreciated.
In you example, A must be a friend of B and not of C to let it access members of B:
class A;
class B {
friend class A;
//...
};
// ....
In other terms, it should look like this:
#include<iostream>
using namespace std;
class A;
class B {
friend class A;
private:
int _b;
public:
B() : _b(5) {}
};
class A {
public:
int get_a(B& b) {
cout << b._b;
}
};
class C {
private:
A a;
B b;
public:
A& get_A() {
return a;
}
B& get_B() {
return b;
}
};
int main() {
C c;
c.get_A().get_a(c.get_B());
}
That being said, you should probably reconsider your design to avoid such a strong dependency between your classes and get rid of friends.
Your code looks really confused. I'm not sure what you are trying to do in the second piece of code. The only place you can enable access to members of class B is in class B. You can do this either through making those members public or protected, adding accessor functions for the members or setting another class to be a friend class of class B by adding a friend class declaration inside class B.
Personally I would go with accessor functions as this means you are reducing class to class dependencies. Any class that has internal access to class B, by being made a friend or having direct access to member variables because they are public, is then dependent on the structure of class B.
I have class A and B.
class A{
public:
foo();
};
class B : public A{
public:
int x;
};
Assume that there is an object from B class in a test file.How should I call foo function?
object.foo(); // or
object.A::foo();
Other questions:
When do we call a function like that?What if I do multiple inheritance?
Simply object.foo(), and there's not much more to add:
B object;
object.foo();
class B inherits public members of class A, so function foo() also belongs to class B and can be called using B class's object.
B b;
b.foo();
You need to know inheritance in c++. Its just same as
b.x;
See x and foo() both are member of object b even b is object of Class B and its possible because Class B inheritance features from Class A, In your code function foo().
Note Class A has only one member function foo()
A a;
a.foo();
Is valid, But
a.x;
Is not valid
EDIT: Multi-level inheritance Class C inherits Class B and Class B inherits Class A, then
class C : public B{
public:
int y;
};
C c;
c.foo(); // correct
Is also valid.
And
c.x;
c.y;
Also valid, x, y, foo() all are member of Class C.
Notice: What I told you is multi-level Multiple inheritance in C++ is different. Also three access specifiers in C++ are very important in case of inheritance: public private protected in c++
I have internal objects, which should'nt be used by client code :
class InternalA {};
class InternalB {};
I have public interface objects A, B, C. Internally, i need to construct objetcs InternalA from A and InternalB from B, but A and B can only be accessed by a pointer to base class C. I could use covariant virtual method but doing so, my Internals become public, and InternalA and InternalB are not really two subtytes of the same base class.
Or i could do something like that :
class C {
// some data
public:
C() {};
// some pure virtual methods and virtual methods
virtual C *getConcrete(void) const =0;
};
class B : C {
public:
//methods
virtual B *getConcrete(void) { return static_cast<B>(this); };
};
class A : C {
public:
//methods
virtual A *getConcrete(void) { return static_cast<A>(this); };
};
And then use an internal builder with polymorphic method in A or B parameter.
Edit :
To build InternalA and InternalB, i can use a function/method like that :
void somefunction(A *a) {
InternalA x(<using a->smthg>);
// do stuffs
};
void somefunction(B *b) {
InternalB x(using b->smthg>);
//do stuffs
};
What do you think about this hack ?
I think its impossible to solve this problem using only class C. To build InternalA or InternalB you need knowledge about A or B. At builder definition A or B must be defined. So I think you should use dynamic_cast. Or some kind of type id implemented by virtual functions if dynamic_cast is prohibited.
#include "A.h"
......
InternalA* buildInternalA(const C* c) {
const A* a = dynamic_cast<const A*>(c);
if (a)
return new InternalA(a);
return 0;
}
But where you use builder(in other cpp file), you don`t need definition of A and B, only declaration of builder:
class InternalA;
class C;
InternalA* buildInternalA(const C* c);
I have class A which has only private members (inclusive data, methods, constructors, destructor .... ). Also I have class B which is friend of class A. And I want all derived classes of B (also there are templates which are inherited from B) to be friends of class A too. Is there any way to do this?
C++ doesn't support this directly: "a kid of my friend is not my friend".
You have to use another way to implement this; for example, define a set of protected accessor functions in class B:
class A {friend class B; int x, y};
class B
{
protected:
int& AccessX(A& a) {return a.x;}
int& AccessY(A& a) {return a.y;}
}
This is only feasible if class A is very small.
If class A is large, you will have to think what exactly you want class B and its derived classes to do with class A, and express it as a set of functions. Define these as protected functions in class B:
class A
{
A(): x(42), y(99) {}
friend class B;
int x, y;
}
class B
{
protected:
A Create() {return A();}
void Manage(A& object) {object.x += 1; object.y += 2;}
}