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;}
}
Related
Suppose we have a class A:
class A{
int a_;
public:
friend class B;
A(int a):a_(a){}
int getA(){ return a_;}
void setA(int a){a_ = a;}
void print(int x){cout << x << endl;}
};
and another class B:
class B{
int b_;
public:
B(int b):b_(b){}
void setB(int b){b_ = b;}
int getB(){return b_;}
//friend void A::print(int x);
};
How to use a method of class A like print() using an object of class B?
//main.cpp
B b1(10);
b1.print(b1.getB());
Short answer: No, a friend class's object cannot access the methods of the class of which it is a friend. It can only access the data members(private or protected).
To access the members of the class with which a class is a friend, use the object of the appropriate class.
Suppose, class B is a friend to class A, to access the members of the class A, always use the objects of the class A. In no case, an object of class B can be used to access the members of class A, be it private, public or protected.
How to use a method of class A like print() using an object of class B?
B isn't related to A in any way so you can't. The only thing you've done by adding a friend declaration is that you've allowed class B(or B's member functions) to access private parts of class A through an A object. Note the last part of the previous sentence. We still need an A object to be able to call A::print().
That is, friendship doesn't mean that you can directly(without any A object) access A's private members.
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.
}
};
I have a class
class A
{
.....
private:
int mem1;
int mem2;
}
I have another class B which need to access only to mem1.
class B
{
....
}
How can I access private member mem1 from only from class B? I don't want to use friend. This means access to all private members.
With some rearrangement to class A (which might not necessarily be acceptable), you can achieve this:
class Base
{
friend class B;
int mem1;
};
class A : public Base
{
int mem2;
};
This exploits the fact that friendship is not transitive through inheritance.
Then, for class B,
class B
{
void foo(A& a)
{
int x = a.mem1; // allowed
int y = a.mem2; // not allowed
}
};
You can write a base class with member mem1 and friend B
class Base {
protected:
int mem1;
friend class B;
};
class A: private Base {
// ...
};
I am put/get value in/from subclass B from object of base class A. But I am not able to assign or get the value. My code is:
class A
{
};
class B: A
{
string SID;
};
class C: A
{
string Name;
};
class D : A
{
string Name;
};
class E
{
A a;
UINT32 AccessLevel;
};
.......
main()
{
E e;
}
Using object of e am trying to get the value of subclass B.
I need to get the SID from the class B?
Thanks,
The C++11 standard 11/3 says:
Members of a class defined with the keyword class are private by default.
at 11.2/2
In the absence of an access-specifier for a base class [...] private is assumed when the class is defined with the class-key class.
and at 11.2/1:
If a class is declared to be a base
class for another class using the private access specifier, the public and protected members of the base
class are accessible as private members of the derived class.
So what does that mean? First of all:
class A {};
class B : A {};
Here A, by virtue of 11.2/2 is inherited privately. This may be okay if you want to inherit variables and you want to implement getter/setters for a variable only in a derived class, but that's usually considered bad style.
In your case however, as stated by 11/3, your members are not inherited at all because they are private members:
class A
{
public:
int a; // inherited
protected:
int b; // inherited
private:
int c; // NOT inherited
};
and especially
class A { int a; };
is equivalent to
class A { private: int a; };
So you could make your members accessable from within your derived classes by making them public or protected (see 11.2/1):
class A { public: int a; };
class B : A {}; // privately inherits a
and if you wanted to make it acessable from outside of your derived classes you will have to inherit as public as well:
class A { public: int a; };
class B : public A {}; // publicly inherits a
but that's not what you usually would do. It's considered better style to make variables private and expose only getters and setters for those:
class A
{
public:
int get_a() const { return a_; }
void set_a(int val) { a_ = val; }
private:
int a_;
};
class B : public A {}; // now publicly inherits the getters and setters
// but not a_ itself
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);
};