a. 类型(赋值)兼容性原则的说明: 需要基类对象的任何地方,都可以用公有派生类对象代替。通过公有继承,派生类得到了基类中除构造函数和析构函数以外的所有成员。实际上,公有派生类实际具备了基类的所有功能,凡是基类能解决的问题,公有派生类都可以解决。
b. 类型(赋值)兼容性原则可以代替的情况:
代替之后,派生类对象可以直接作为基类的对象使用,但是只能用从派生类继承的成员。
a.第一个层次:
//P父类 C子类
P* p =NULL;
C c;
p =&s;
void P(P* p);
void P(P& p);
b.第二个层次:
C c;
P p =c;
C c;
P p;
p =c;
a. 一个类中的对象模型:
class A
{
protected:
int a;
}
创建A类的对象时,会将成员函数和成员变量分开存储。a. 普通的成员变量存储在变量中; b. 静态的成员变量存储在全局区; c.成员函数存储在代码片段区。
b. 继承中的对象模型:
class A
{
protected:
int a;
}
class B:public A
{
protected:
int b;
}
(子类是由父类成员和新的子类成员叠加得到的)
问题: 对象b中对于变量a和b初始化是一样的吗???
不一样,子类对象构造时,需要调用父类的构造函数对其继承的成员变量初始化。子类对象析构时,会调用父类的析构函数对其继承的成员进行清理。—–》分工明确
a. 子类对象在创建时会首先调用父类的构造函数;
b. 父类构造函数执行完毕后,执行子类的构造函数;
c. 当父类的构造函数中有参数时,必须在子类的初始化列表中显示调用;
d. 析构函数执行的顺序和构造函数的执行顺序相仿。
//写子类的构造函数时,必须要看看父类的构造函数能否被自动调用;
//若不能被自动调用,应该显示调用
class A
{
int a;
public:
A(int a)
{
this->a = a;
}
};
class B:public A
{
int b;
public:
B(int b):A(10)
{
this->b = b;
}
};
class C
{
int c;
public:
C(int c)
{
this->c = c;
cout << "组合对象" << endl;
}
};
class A
{
int a;
public:
A(int a)
{
this->a = a;
cout << "父类" << endl;
}
};
class B:public A
{
int b;
C c;
public:
B(int b,int a,int c):A(a),c(c)
{
this->b = b;
cout << "子类" << endl;
}
};
int main()
{
B b(20,10,5);
return 0;
}
输出结果:
继承与组合对象混搭情况,构造与析构调用规则结论:
a. 先调用父类的构造函数,再调用组合对象的构造函数,最后调用自己的构造函数;
b. 先调用自己的析构函数,再调用组合对象的析构函数,最后调用父类的析构函数。
a. 当子类的成员变量和父类的成员变量同名时,子类依然从父类中继承同名变量,但是子类的同名变量会屏蔽父类的同名变量。子类中使用父类名+作用域符使用父类的同名成员变量。同名变量存储在不同的内存中。
b. 继承的同名成员变量和成员函数类似。
class A
{
int x;
public:
int a;
A(int a)
{
this->a = a;
cout << "父类" << endl;
}
};
class B:public A
{
int a;
public:
B(int a,int b):A(a)
{
this->a = b;
cout << "子类" << endl;
}
void printF()
{
cout << A::a << endl;
}
};
int main()
{
B b(20,10);
cout << sizeof(b) << endl;
A a(10);
cout << sizeof(a) << endl;
return 0;
}
a. 基类定义的静态成员将被所有的派生类共享;
b. 根据static成员自身的访问特性和派生类的继承方式,在类中具有不同的访问性质;
c. 派生类中访问静态成员,使用以下两种形式:
class A
{
public:
static int x;
int a;
public:
A(int a)
{
this->a = a;
x +=10 ;
cout << "父类" << endl;
}
};
int A::x = 50;
class B:public A
{
int a;
public:
B(int a,int b):A(a)
{
this->a = b;
x += 10;
cout << "子类" << endl;
}
void printF()
{
cout << A::a << endl;
}
};
int main()
{
B b(20,10);
cout << sizeof(b) << endl;
A a(10);
cout << sizeof(a) << endl;
cout << A::x << endl;
return 0;
}