I开发者_运维技巧 have the following code:
class A {
private:
int i;
};
class B : public A {
private:
int j;
};
When I check sizeof(B)
, it appears to be sizeof(base) + sizeof(derived)
. However, my understanding of inheritance is that the private
members of a base class are not inherited. Why then are they included in the result of sizeof(B)
?
all member variables are inherited. the private protected public
modifiers only alter who has access to those variables
You misunderstand what private
does. In your code snippet it simply prevents non-members and non-friends of A
from accessing i
. It's just an access-control modifier. Instances of B
will have data members of A
, even though B
won't have (direct) access to it.
An analogy that shows that this does in fact make sense:
class Human
{
protected:
void UseCognitivePowers() { brain.Process(); }
private:
Brain brain;
// ...
};
class StackOverflowUserInSilico : public Human
{
private:
void AnswerStackOverflowQuestion(int questionId)
{
// ...
// magic occurs here
// ...
UseCognitivePowers();
}
};
Even though brain
is private in the Human
class, StackOverflowUserInSilico
will have a Brain
since StackOverflowUserInSilico
derives from Human
. This is needed, otherwise the UseCognitivePowers()
function won't work even though StackOverflowUserInSilico
inherits the method from Human
.
Of course whether subclasses of Human
will actually take advantage of the UseCognitivePowers()
method afforded to them by the Human
class is a totally different matter.
You either misunderstand sizeof
or your misunderstand the layout (in memory) of C++ objects.
For performance reason (to avoid the cost of indirection), compilers will often implement Derivation using Composition:
// A
+---+
| i |
+---+
// B
+---+---+
| A | j |
+---+---+
Note that if private
, B
cannot peek in A
even though it contains it.
The sizeof
operator will then return the size of B
, including the necessary padding (for alignment correction) if any.
If you want to learn more, I heartily recommend Inside the C++ Object Model by Stanley A. Lippman. While compiler dependent, many compilers do in fact use the same basic principles.
It is inherited - the derived class object will contain it, but it can't be accessed by member functions of the derived class.
This has already been answered in a few other answers: access specifiers restrict access, but the member attributes of the class are still inherited.
I just wanted to provide a rationale, as I usually learn better when I see the reasons for that. Basically, when you inherit from an type, the derived type contains a subobject of the base type, as small or large as the base might be. The reason for needing all of the member variables is that the derived object is a base object, and base level member functions can be called on it. Even if the derived type cannot access the private member attribute, the base methods that can be called on that object might still need to access it, so the members must be there:
class base {
int x;
public:
base() : x(0) {}
// ...
void printout() {
std::cout << x << std::endl;
}
};
class derived : public base {
// ... assume that derived does not hide `printout`
};
int main() {
derived d;
d.printout(); // this requires access to d.base::x
}
This is only a simple example, and there are a few things that you can say here to argue that in some cases x
can be made unneeded (we are overriding/hiding printout
in the derived object...) but the language still allows you to access a hidden/overridden member method by qualifying, so d.base::printout()
would still access printout
at the base level, and that in turns requires x
.
Access specifiers (public/private/protected) don't affect inherited "object size" in anyway.
i dont know what language this is, but when you inherit the original object still exists. that is why you can still call base.method()
精彩评论