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
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'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);
}
};
class base {
public:
int getC() {return c;}
int a;
protected:
int b;
private:
int c;
}
class derived: public base {
public:
int getD() {return d;}
private:
int d;
}
Now, class derived has public member:
int getC() {return c;}
int getD() {return d;}
int a;
protected member:
int b;
private member:
int d;
I can't comfirm if int c; is a private member of class derived. It's clear that any new member function of class derived can't access c. So, if c is a private member of class derived, the member function of class derived should have right to access c. So c is a what kind of member of class derived?
A derived class doesn't inherit access to private data members. However, it does inherit a full parent object, which contains any private members which that class declares.
Have a look at this question
I will clarify this with an example.
Consider a house where public variables and methods are outside your
house. Anyone who knows your house(class object) can access them.
Protected variables and methods are like common areas in your house like hall, kitchen only members inside your house can access them.
Private members are like your parent's room (base class)(ie only your parent can go into their room and you don't know what is inside)
Now coming to the question each class access modifier has the following arrangement
base
private : int c;
protected : int b;
public : int getC() {return c;}
int a;
derived
private : int d; (derived will never know c's existense)
protected : int b; (base class's copy)
public : int getC() {return c;}
int a;
int getD() {return d;}
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 {
// ...
};
say I have this example :
class A1
{
private:
string name;
}
class A
{
private:
A1* field;
}
class B1 : public A1
{
private:
int id;
}
class B : public A
{
private:
B1* field;
}
so in this case I would have in my B class:
id attribute from the B1 class
name attribute coming from the inheritance of the class A.
another name attribute coming form the inheritance of B1 class from the class A1.
So what should I do to avoid this redundancy ?
I don't see any redundancy here. Let's rename the classes into something more useful:
class Animal // A1
{
private:
string name;
}
class Person // A
{
private:
Animal* housePet;
}
class Dog : public Animal // B1
{
private:
int breedId;
}
class DogTrainer : public Person // B
{
private:
Dog* trainee;
}
You see, no field can be safely eliminated. The trainee is not the same as the housePet, each of them needs a separate name.
No, you haven't any redundancy.
B class didn't inherit any member from its base classes because they have been declared as private (then visible and accessible only from within the class they are declared).
For example:
class A
{
private:
int _privateMember;
protected:
int _protectedMember;
public:
int _publicMember;
};
class B : public A
{
void test()
{
// This doesn't work, this field is private to the class
// where it has been declared (A)
_privateMember = 1;
// This works, a protected member is accessible inside the class
// where it's declared and derived classes.
_protectedMember = 1;
// This works, a public member is always visible and accessible.
_publicMember = 1;
}
};
void test()
{
A a;
// This doesn't work, a private field isn't accessible outside the class
// where it has been declared
a._privateMember = 1;
// This doesn't work, a protected member is accessible only inside the class
// where it has been declared and its derived classes
a._protectedMember = 1;
// This works, a public member is always visible.
a._publicMember = 1;
}
Things can be more complicated than this, you do not need to always use public inheritance, for example:
class C : protected A
{
};
void test()
{
C c;
// This doesn't work! Field is public for its class but C has inherited from A
// in a protected way (so only derived classes know that it derives from A).
c._publicMember = 1;
}
Moreover you can make all private members of a class visible to another class or function using the friend declaration:
class D
{
private:
int _privateMember;
public:
int _publicMember;
friend class DFriend;
};
class DFriend
{
void test()
{
D d;
// This works, public members are accessible
d._publicMember = 1;
// This works too, this class is a friend of D
d._privateMember = 1;
}
};
That said remember that when you derive from a base class you say "derived class is of type base class". For example you have a base class to describe a planet with some properties (modeled for simplicity as public fields):
class Planet
{
public:
int Diameter;
};
Then suddenly you discover you have to make it more general and you add a more general base class called CelestialBody:
class CelestialBody
{
public:
bool canCapture(CelestialBody anotherBody)
{
// Some calculations
}
private:
vector<CelestialBody> _capturedBodies;
};
class Planet : public CelestialBody
{
public:
int Diameter;
};
Now you say this:
A celestial body is something that can capture another celestial body;
A celestial body keeps a private list of captured bodies because they may change some of its properties.
A planet is a celestial body.
A planet has a public (integer) property to describe its diameter in Km.
Private members of CelestialBody aren't visible outside of it (kind of implementation details). World knows that a Planet is a CelestialBody (because of public inheritance) then everything was public in CelestialBody is public in Planet too.
If you do not want to say this then you shouldn't simply use inheritance. Take a look to this articles:
Composition and inheritance: when to inherit from another object and when to include another object as field.
Incapsulation: incapsulation of informations inside a class.