let's say we have class A,B,C,D where A is base, B,C are between and D is derived in diamond model.
NOTE:
class B inherits virtualy class A in private mode,
class C inherita virtualy class A in protected mode.
class A
{
public:
int member; // note this member
};
class B :
virtual private A // note private
{
};
class C :
virtual protected A // note protected
{
};
class D :
public B, // doesn't metter public or whatever here
public C
{
};
int main()
{
D test;
test.member = 0; // WHAT IS member? protected or private member?
cin.ignore();
return 0;
}
now when we make an instance of class D what will member be then? private or protected lol?
Figure No2:
what if we make it so:
class B :
virtual public A // note public this time!
{
};
class C :
virtual protected A // same as before
{
};
I suppose member will be public in this second example isn it?
§11.6 Multiple access [class.paths]
If a name can be reached by several paths through a multiple inheritance graph, the access is that of the path that gives most access. [ Example:
class W { public: void f(); };
class A : private virtual W { };
class B : public virtual W { };
class C : public A, public B {
void f() { W::f(); } // OK
};
Since W::f() is available to C::f() along the public path through B, access is allowed. —end example ]
I think I don't need to add anything else, but see also this defect report (which was closed as "not a defect").
Related
I'm learning c++ here.
I'm learning more about inheriting and classes but I'm having the following issue:
class A
{
public:
std::vector<int> vect1;
};
class B : A
{
public:
int x, y;
};
class C : B
{
c()
{
x=10;
y=30;
vect1.pushback(44);
}
};
why cant i access vect1 from the class C? how can i achieve this?
i also tried:
class C : B, A {...}
but then it said vect1 is ambiguous (or something like that). im using visual studios.
thank you.
why cant i access vect1 from the class C?
Because vect1 has private access. Sub classes can not access private members of a base class. They can only access protected or public members.
Furthermore, A is a private base of B, so sub classes of B have no access to it. Only protected or public bases are accessible to grand children.
The default access specifier of classes defined with the class keyword is private (The default is public for classes defined with the keyword struct). To declare a base with another access specifier, you can put the access specifier keyword right before each base in the declaration:
class B : protected A
{
// ...
};
To declare members with another access specifier:
class A
{
protected:
std::vector<int> vect1;
};
To get access from derived to base class you should do both:
public inheritance
protected declaration
like the following:
#include <vector>
class A
{
protected:
std::vector<int> vect1;
};
class B : public A
{
protected:
int x, y;
};
class C : public B
{
public:
C(){
x=10;
y=30;
vect1.push_back(44);
}
};
How instances of virtual base class are available to derived class,How it can be implemented in following code ?
class A
{
public:
void test();
};
class B : virtual public A
{
};
class c : public A
{
} ;
class D : public B, public C
{
};
See inscribed comments with corrected version:
class A
{
public:
void test();
};
class B: virtual public A // A is a virtual base class
{
};
class C : public A // C is a base class of A
{
} ;
class D: public B, public C // D has two base classes B and C
{
};
By virtue of inheritance, D gets two copies of A, one via B, another via C
You could have only one shared copy of A in D, if you would have declared:
class C : virtual public A // C is a virtual base class of 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
Is it possible to access base class public member from instance of derived class in some other locations in the program.
class base {
public:
int x;
base(int xx){
x = xx;
}
};
class derived : base {
public:
derived(int xx) : base(xx){
}
};
class main {
public:
derived * myDerived;
void m1(){
myDerived = new derived(5);
m2(myDerived);
}
void m2(derived * myDerived){
printf("%i", myDerived->x);
}
};
After above code, I got following error.
`error: 'int base::x' is inaccessible`
The problem is that you accidentally use private inheritance here
class derived : base {
This makes all base class members private in the derived class.
Change this to
class derived : public base {
and it will work as expected.
You inherit privately from the base class. What you typically need is public inheritance:
class derived : public base
Here is the FAQ on private inheritance.
You should inherit from base publicly, then.
class derived : public base {
public:
derived(int xx) : base(xx){
}
};
Private inheritance is used in very specific circumstances, such as when you have a has-a relationship between two classes, but you also need to override a member of the base class.
From outside the class, you can only access public members of public base classes; and inheritance is private by default when you define a class using the class keyword.
To make it accessible, you need public inheritance:
class derived : public base
^^^^^^
Try:
class derived : public base {
...
};
Use public inheritance:
class derived : public base {
...
};
or
Make x private instead of public and use following code:
class Base {
int x;
public:
Base (int xx) {
x = xx;
}
void display() {
cout << "x = " << x << endl;
}
};
class Derived : public Base {
public:
Derived (int xx) : Base (xx) {
}
};
int main() {
Derived d1(2);
Derived *d = new Derived(10);
d->display();
d1.display();
return 0;
}
Derived class function cannot access even the public members of the base class when the access specifier is private. But how is it that the function 'xyz' of my derived class able to call 'showofb'?
I even tried it by calling the function 'showofb' in the constructor of C. In both cases it works.
How is it able to call the function 'showofb' ?
class B
{
public:
B()
{
cout<<":B:"<<endl;
}
void showofb()
{
cout<<"show of b"<<endl;
}
};
class C : private B
{
public:
C()
{
cout<<":C:"<<endl;
}
void xyz()
{
showofb();
}
};
int main()
{
C c1;
c1.xyz();
}
Private inheritance inherits the public members of the parent as the private members of the child. A class can call its own or inherited private members.
Consider this:
class B
{
public:
B()
{
cout<<":B:"<<endl;
}
void showofb()
{
cout<<"show of b"<<endl;
}
};
class C : private B
{
public:
C() {}
};
class D : public B
{
public:
D(){};
}
int main()
{
C c1;
c1.showofb(); // WONT WORK
D d1;
d1.showofb(); // WILL WORK
}
B::showofb() is a public function. So it can be called by C. If you modify B to make showofb private, C will no longer be able to call it.
The private inheritance means that all public and protected members of B are inherited as private by C. So C can still call public and protected members of B, but any classes derived from C will not be able to call members of B.
user1001204, you appear to have a mistaken concept of private inheritance. That class C inherits from class B via private inheritance means that the inheritance relationship is hidden to anything that uses class C. Private inheritance does not hide the inheritance relationship inside Class C itself.