c++ inherit
子类继承父类,如果没有虚基,那么即使变量的类型和名字相同,编译器也会给父类的变量分配内存。以C c为例 内存结构布局如下,所以总大小为20个字节
#include <iostream> using namespace std; class A { public: A() : x_(1) {} void print() { cout << "A::print() x_ = " << x_ << endl; } int x_; }; class B1 : public A { public: B1() : x_(2) {} void print() { cout << "B1::print() x_ = " << x_ << endl; } int x_; }; class B2 : public A { public: B2() : x_(3) {} void print() { cout << "B2::print() x_ = " << x_ << endl; } int x_; }; class C : public B1, public B2 { public: C() : x_(4) {} int x_; }; int main() { cout << "sizeof(int):" << sizeof(int) << endl; cout << "sizeof(int *):" << sizeof(int *) << endl; cout << "sizeof(A):" << sizeof(A) << endl; cout << "sizeof(B1):" << sizeof(B1) << endl; cout << "sizeof(B2):" << sizeof(B2) << endl; cout << "sizeof(C):" << sizeof(C) << endl; cout << endl; C* c = new C; int *sp = (int *) c; cout << "sp:" << sp << endl; // A* a = c; // comiple error: ‘A’ is an ambiguous base of ‘C’ // A* a = (A*) c; // compile error: ‘A’ is an ambiguous base of ‘C’ cout << "(B1*) c:" << (B1*) c << endl; //值是在做强转的时候发生变化的,而不是赋值的时候发生变化 cout << "(B2*) c:" << (B2*) c << endl; A* a1 = (B1*) c; A* a2 = (B2*) c; B1* b1 = c; B2* b2 = c; cout << "a1:" << a1 << ", a2:" << a2 << endl; c->B1::print(); c->B2::print(); a1->print(); a2->print(); b1->print(); b2->print(); cout << endl; a1->x_ = 11; a2->x_ = 22; cout << "a1->x_ = " << a1->x_ << ", a2->x_ = " << a2->x_ << endl; cout << "c->B1::x_ = " << c->B1::x_ << ", c->B2::x_ = " << c->B2::x_ << endl; cout << endl; cout << "*(sp + 0):" << *(sp + 0) << endl; cout << "*(sp + 1):" << *(sp + 1) << endl; cout << "*(sp + 2):" << *(sp + 2) << endl; cout << "*(sp + 3):" << *(sp + 3) << endl; cout << "*(sp + 4):" << *(sp + 4) << endl; return 0; }
result:
sizeof(int):4 sizeof(int *):8 sizeof(A):4 sizeof(B1):8 sizeof(B2):8 sizeof(C):20 sp:0x18ee010 (B1*) c:0x18ee010 (B2*) c:0x18ee018 a1:0x18ee010, a2:0x18ee018 B1::print() x_ = 2 B2::print() x_ = 3 A::print() x_ = 1 A::print() x_ = 1 B1::print() x_ = 2 B2::print() x_ = 3 a1->x_ = 11, a2->x_ = 22 c->B1::x_ = 2, c->B2::x_ = 3 *(sp + 0):11 *(sp + 1):2 *(sp + 2):22 *(sp + 3):3 *(sp + 4):4
C的存储结果如下
0x2564020 C::x_ //高地址
0x256401C B2::x_
0x2564018 B2::A::x_
0x2564014 B1::x_
0x2564010 B1::A::x_ //低地址
A* a = (B1*) c;
则指针指向B1::A::x_
A* a = (B2*) c;
则指针指向B2::A::x_
(1) 成员函数的覆盖:子类对父类的成员函数覆盖,必须函数名称一致,参数一致,返回值一致;
(2) 成员变量的覆盖:子类覆盖的仅仅是继承来的那个成员变量,而并不改变原来父类中的变量;
(3) 访问函数(或变量)取决于被赋予的类型,采用往上的就近原则,如果自己有则首先调用自己的函数, 如果父类存在相关接口则优先调用,如果父类不存在则调用祖父类接口;
(4) 和java一样,不允许声明这样的函数:函数名和函数参数列表相同,而返回类型不同。这样编译会报错。
虚基类见 http://www.cnblogs.com/muhe221/articles/4982211.html

浙公网安备 33010602011771号