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

posted @ 2015-11-18 23:13  牧 天  阅读(565)  评论(0)    收藏  举报