I have the following query;
classB inherits from classA
classC is friend of classB
Doesn't this mean classC should be able to access protected member of classA? Since classB inherits this from classA, an classC can access everything in class classB?
[My original answer was nonsense. Apologies for that. Thank you to #celtschk for pointing that out and providing the better answer.]
If C is a friend of B, it can access all of B's members, whether private, public, or protected, and that includes the accessible (public and protected) members that are part of a base subobject:
struct A { protected: int a; };
struct B : A { private: int b; friend struct C; }
struct C
{
B x;
A w;
void f()
{
x.a = 1; // fine
x.b = 2; // fine
// w.a = 0; /* Error, #1 */
}
friend struct D; // see below
};
However, friendship is neither transitive nor inherited: C is a friend of B, but not of A (see #1). Also, if D is a friend of C, then D doesn't get any of the access that C's friendship to B affords it, so D cannot access B's non-public members. Similarly, if struct E : C inherits from C, then E is also not a friend of B automatically:
struct D
{
B y;
void g()
{
// y.b = 3; /* Error! */
}
};
struct E : C
{
B z;
void h()
{
// y.b = 4; /* Error! */
}
}
Perhaps one can summarize what's going on in a few points:
A derived class has access to all public and protected members of each base class.
A friend of a class has access to all members of that class that are accessible to it (i.e. all members excluding private base members).
Friendship is not inherited: If a class has a friend, that friendship does not apply to any of its base classes nor to any of its derived classes.
A friend of a friend is not a friend.
It means that classC should be able to access the protected classA subobject part of classB. It should not be able to access anything non-public from classA itself.
For example:
class C;
class A
{
protected:
int i;
};
class B:
public A
{
friend class C;
};
class C
{
public:
void foo(A& a, B& b)
{
// a.i = 3; // not allowed
b.i = 3; // allowed, accesses the `i` of the `A` subobject of `B`
}
};
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.
}
};
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 {
// ...
};
The following code is giving me the error that 'A' is an inaccessible base of 'B' and I am not sure why:
class A {};
class B : protected A {};
A foo( A a );
///
B b;
foo(b);
Any explanation for this much appreciated.
Edit: I suppose I am just confused about the nature of protected inheritance. I thought it meant that any derived class (in this case of A) could inherit its variables and its functions.
A class that inherits the protected parent class can get to it, otherwise it is considered private:
class A {};
class B : protected A {};
A foo(A a) { return a; };
class C : public B {
public:
A foo(C c) { return c; };
};
int main() {
B b;
//foo(b); // Can't implicitly convert, A is protected (might as well be private from this line's perspective)
C c;
A a = c.foo(c); // class C can get A
}
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
Why is that protected members in the base class where not accessible in the derived class?
class ClassA
{
public:
int publicmemberA;
protected:
int protectedmemberA;
private:
int privatememberA;
ClassA();
};
class ClassB : public ClassA
{
};
int main ()
{
ClassB b;
b.protectedmemberA; // this says it is not accesible, violation?
//.....
}
You can access protectedmemberA inside b. You're attempting to access it from the outside. It has nothing to do with inheritance.
This happens for the same reason as the following:
class B
{
protected:
int x;
};
//...
B b;
b.x = 0; //also illegal
Because the protected members are only visible inside the scope of class B. So you have access to it here for example:
class ClassB : public ClassA
{
void foo() { std::cout << protectedMember;}
};
but an expression such as
someInstance.someMember;
requires someMember to be public.
Some related SO questions here and here.
You can only access protectedmemberA from within the scope of B (or A) - you're trying to access it from within main()