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.
Related
I have a derived class (class B) from a base class (class A). Class A has a protected virtual function foo() which I want to override and use it as private in derived class.
Class A{
protected:
virtual void foo() = 0;
}
I am wondering whether the following
Class B: public Class A
private:
virtual void foo();
and
Class B: private Class A
private:
virtual void foo();
are the same.
They are not the same. In the first example, B is-an-A, in the second it isn't. So in the first case you can have code such as
void foo(const A& a);
which accepts A and B as arguments. With private inheritance, you could not do that. For example,
A a;
B b;
foo(a); // OK with private and public inheritance
foo(b); // OK only with public inheritance, i.e. B is an A.
No, your two cases are not the same.
In the second case class B can't be casted to class A, because a private base class is hidden. in this aspect would get the same behavior as if class A would be a member of class B.
No both are not same
In public inheritance class A's foo() will be protected member in class B
In private inheritance class B can only access the public members of the class A so there will not present any foo() of class A in class B.
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);
};
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 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;}
}
I was reading the C++ faqs on http://www2.research.att.com/~bs/bs_faq2.html , when i came accross this code to implement a 'sealed' class:
class Base{
public:
friend class A;
private:
Base(){cout<<"Base constructor called";}
};
class A : public virtual Base{
public:
A(){cout<<"A const called";}
};
class B : private A{};
int main(){
A a;
//B b;
return EXIT_SUCCESS;
}
I did not understand how by using the virtual keyword, 'sealed' class effect is achieved. If i remove the virtual keyword, then it has no 'sealed' effect. Why?
It works because due to the way virtual inheritance works, B must construct Base- which it can't, because Base's constructor is private. Only A can construct Base. In normal inheritance, B constructs A, which constructs Base, which is fine because A can construct Base and B can construct A.