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
}
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 encountered the following response in a thread :
Protected members can be accessed from derived classes. Private ones can't.
class Base {
private:
int MyPrivateInt;
protected:
int MyProtectedInt;
public:
int MyPublicInt;
};
class Derived : Base
{
public:
int foo1() { return MyPrivateInt;} // Won't compile!
int foo2() { return MyProtectedInt;} // OK
int foo3() { return MyPublicInt;} // OK
};
class Unrelated
{
private:
Base B;
public:
int foo1() { return B.MyPrivateInt;} // Won't compile!
int foo2() { return B.MyProtectedInt;} // Won't compile
int foo3() { return B.MyPublicInt;} // OK
};
...
1) my question is:
I have read : "A class derivation list names one or more base classes and has the form:
class derived-class: access-specifier base-class
Where access-specifier is one of public, protected, or private, and base-class is the name of a previously defined class. If the access-specifier is not used, then it is private by default. " and "Private Inheritance: When deriving from a private base class, public and protected members of the base class become private members of the derived class.
"
SO...in our example class Derived : Base is equivalent to class Derived : private Base because no access-specifier has been defined, yet the code works as the writer said, so what am i missing?- i thought that Base class for the class Derived access-specifier is private therefore public and protected members of Base should be private for class Derived and can't be accessed... thanks!
Its a similar kind of idea. Rather than applying to which members of the class you can access, it applies to which base classes you can access.
class A
{
public:
void f();
};
class B : public A
{
public:
void g()
{
f(); // OK
A *a = this; // OK
}
};
class B2 : public B
{
public:
void h()
{
f(); //OK
A *a = this; // OK
};
};
B b;
A& ba = b;
class C : protected A
{
public:
void g()
{
f(); // OK, can access protected base
A *a = this; // OK, can access protected base
}
};
class C2 : public C
{
public:
void h()
{
f(); // OK, can access protected base
A *a = this; // OK, can access protected base
};
};
C c;
c.f(); // Not OK, allthough A::f() is public, the inheritance is protected.
A& ca = c; // Not OK, inheritence is protected.
class D : private A
{
public:
void g()
{
f(); // OK because A is a base of D
A *a = this;
}
};
class D2 : public D
{
public:
void h()
{
f(); //Not OK, A is inherited with private in D
A *a = this; //Not OK
};
};
D d;
d.f(); // Not OK, allthough A::f() is public, the inheritance is private.
D& da = d; // Not OK, inheritence is private.
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 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`
}
};
Although I made the members of both base and derived classes public, Why does the conversion says that it is inaccessible?
class B
{
public:
int var;
};
class D: private B
{
public:
int var;
};
int main()
{
D d;
Base &b = d; //my error
}
You can't convert from a derived class to a non-public base class (well, outside the class itself anyway). Private inheritance is typically used as a form of composition, not for substitution so there's no need to convert to the base. In your case it looks like you want substitution so you should use public inheritance.
Try this:
#include <iostream>
class B
{
public:
int var;
};
class D: public B
{
public:
int var;
};
int main()
{
D d;
B &b = d; //my error
}
What you are trying to do won't work with private inheritance. Also note that your base class is known as B and not Base.
Regards,
Dennis M.