I was learning about inheritance. If we have used private access specifier in base class then it is not accessible in derived class.
But I have a doubt regarding this.
#include<bits/stdc++.h>
using namespace std;
class A
{
private:
int a;
int b;
int c;
public:
int d;
void print()
{
cout<<"Inside A Print()"<<endl;
}
};
class B: public A
{
private:
int a1,b1,c1;
public:
B()
{
}
void print()
{
cout<<"Inside B Print()"<<endl;
}
};
int main()
{
B obj;
cout<<sizeof(obj)<<endl;
return 0;
}
Since I have used public access specifier during inheriting class A. Since we know that private member of base class is not accessible at all.
So output of above code should be: 16.
But compiler giving the output as 28.
Can anyone explain this?
The object of class B has inherited the member variables from class A. For example,
class Car {
private:
string color;
};
class BMW : public Car {
private:
string model;
};
Now, any object of BMW will have its own model and color at the same time. But the color member variable won't be accessible unless you write public getters and setter in the Car class.
Related
Please consider the scenario below:
class A
{
friend void B::Itemfunction();
private:
int number;
int size;
public:
Randomfunction();
}
class B : public A
{
private:
string Random;
public:
void Itemfunction();
void CheckLog();
}
Would it be possible for an object made in Itemfunction of type A to access the private data members of obj? Such as:
void B::Itemfunction(){
A obj;
//Possible to do...
obj.number = 2;
}
I understand that the derived class B can access all the public parts of A, but if I wanted just one function (Itemfunction) to access the private parts would this be the correct way of doing it? I just want to see if my understanding is correct.
Cheers
No, it's not possible. You cannot friend a class member function for a class that isn't yet completely declared.
The only way in that case (since class B needs a completely declared class A to inherit), is to forward declare class B; and friend the whole class:
#include <iostream>
#include <string>
class B;
class A
{
// friend void B::Itemfunction();
friend class B;
private:
int number;
int size;
public:
void Randomfunction();
};
class B : public A
{
private:
std::string Random;
public:
void Itemfunction();
void CheckLog();
};
int main()
{
}
Live Demo
In your code, where you implement Itemfunction, you are creating a new, completely unrelated object of type A locally. In inheritance, your B object has an internal subobject of type A. You can access the fields of A directly within B. However, you can't access private members. Your friendship trick will not work; you cannot declare a method of B a friend until you see Bs definition, but B can't be defined until A is defined, and as you can see we're going in circles. What you can do instead is to make that member protected:
class A
{
protected:
int number;
private:
int size;
public:
Randomfunction();
}
void B::Itemfunction() {
number = 2;
}
This has a chicken and egg problem. Both B must be fully defined for A to see B::Itemfunction.
class A
{
friend void B::Itemfunction(); <-- Itemfunction does not exist yet
private:
int number;
int size;
public:
int Randomfunction();
};
class B: public A
{
private:
std::string Random;
public:
void Itemfunction();
void CheckLog();
};
Swapping the order won't work either because B needs A to be defined to inherit from A.
class B: public A <-- A does not exist yet
{
private:
std::string Random;
public:
void Itemfunction();
void CheckLog();
};
class A
{
friend void B::Itemfunction();
private:
int number;
int size;
public:
int Randomfunction();
};
Solution 1 is forward define class B so the compiler knows that B exists, even if it knows nothing about it, and then friend the whole class, because A only knows B exists. OP's friend relationship is maintained.
class B; <-- forward definition of B
class A
{
friend class B; <-- friending all of B, not just the function
private:
int number;
int size;
public:
int Randomfunction();
};
class B: public A
{
private:
std::string Random;
public:
void Itemfunction();
void CheckLog();
};
BUT! All of B now has complete access to all of A. If A wants to keep size or any other members hidden and under it's control, tough. B can call all of A's functions and change all of A's member variables. B can totally pown A.
This also doesn't scale to other subclasses. B can see all of A, but C and D cannot.
So say you have a less trivial example where A cannot allow anyone to mess with the value of size. Maybe it's the capacity of an internal array, and changing size will result in A running past the end of allocated memory. The reason doesn't matter much here; for the sake of this example no one but A is allowed to change size.
This leads us to solution 2: protected access and accessor functions.
class A
{
protected: <-- all inheritors can access members in this block. No one else can
int number;
private: <-- only A can access members in this block
int size;
public:
int Randomfunction();
int getSize() <-- accessor function to provide read-only access to size
{
return size;
}
};
class B: public A
{
private:
std::string Random;
public:
void Itemfunction(); <-- can do anything to number and read size
void CheckLog(); <-- so can this
};
class C: public A
{
private:
std::string member;
public:
void doStuff(); <-- and this
void DoOtherStuff(); <-- and this
};
B and C can access A::number and can use A::getSize to see the value of size. number can be changed by B and C, but size cannot. If you are worried about the cost of calling a function to read size, don't be. When the compiler is done with A::getSize, you won't even know it's there. It probably isn't.
class base
{
private:
int a;
};
class base2
{
private:
int b;
};
class derived:public base,public base2
{
private:
int c;
};
main()
{
base b;
derived d;
cout<<size of(base)<<size of(base2)<<size of(derived);
}
since int a and int b are private variables.so they are not getting inherited in derived class.so the output should be 4 4 4 but it is
output:4 4 12
why?
since int a and int b are private variables.so they are not getting inherited in derived class
That's wrong - of course they are getting inherited, the code in the base class wouldn't be able to work without them. It's just that derived cannot get to them, but it does not change the sizeof the derived class.
Consider this extension of your example:
class base {
private:
int a;
protected:
base() : a(123) {}
void showA() {cout << a << endl;}
};
class base2 {
private:
int b;
protected:
base2() : b(321) {}
void showB() {cout << b << endl;}
};
class derived:public base,public base2 {
private:
int c;
public:
derived() : c (987) {}
void show() {
showA();
showB();
cout << c << endl;
}
};
Even though your derived class cannot read or change a and b, it can show their values by calling the corresponding functions in its bases. Therefore, the variables must remain there, otherwise the showA and showB member functions wouldn't be able to do their work.
private: or protected: or public: annotations on member fields affect only visibility. But the fields are still in the classes.
Take several days to read a good C++ programming book.
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
This is a code fro diamond tree problem of multiple inheritance
and according to me this code is cool but it is showing some error on compilation
..help me to figure the error
#include<iostream>
using namespace std;
class A //A Diamond tree problem
{
int x;
public:
A(int i) { x = i; }
void print() { cout << x; }
};
class B: virtual public A
{
public:
B():A(10) { }
};
class C: virtual public A
{
public:
C():A(20) { }
};
class D: public B, public C{
};
int main()
{
D d;
d.print();
return 0;
}
It would be useful to see the error:
In constructor ‘D::D()’:
error: no matching function for call to ‘A::A()’
When using virtual inheritance, the virtual base class must be initialised by the most derived class. In this case, that is D; so in order to be able to instantiate D, it must initialise A:
class D: public B, public C
{
public:
D():A(42) {}
};
Alternatively, you could provide A with a default constructor. Declaring any constructor will prevent the compiler from implicitly generating one for you.
You need to provide default construct for D and call A in member initialize list:
class D: public B, public C{
public:
D():A(30){}
};
Or you could provide a default A constructor
A():x(0) {}
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.