目录
1.绑定时期
早期绑定:
编译时的多态:函数的重载,运算符的重载
在编译时,就确定了调用关系
晚期绑定:
以虚函数为基础的运行时的多态性
在程序的运行过程中,确定调用关系
2.struct 和 class
struct A {};
class B : A // 默认私有继承
{
};
class A {};
struct B : A //默认公有继承
{
};
3.继承在内存中的表示
4.继承一次
不论是公有继承,私有继承,保护继承,派生类的成员方法都可以访问基类的保护和公有数据成员,但不能访问基类的私有数据成员
5.派生类中含有基类对象
派生类的成员 方法能访问具名基对象的公有,不能访问其私有和保护
6.继承类型
派生类公有继承基类,派生类中的隐藏基对象是其的公有成员
派生类私有继承基类,派生类中的隐藏基对象是其的私有成员
派生类保护继承基类,派生类中的隐藏基对象是其的保护成员
7.继承两次
8. 同名隐藏
派生类的数据成员和基类的数据成员发生命名冲突时,派生类的成员方法访问其时,只访问派生类中的,基类的同名数据成员被隐藏
想要访问隐藏的同名基类数据成员则要用 基类名 + 作用域解析符访问
9. 同名函数的隐藏问题
只有公有继承才存在基类中同名函数隐藏的问题,因为类外不能访问私有和保护成员
#include <iostream>
using namespace std;
class A
{
private:
int value;
public:
A() :value(10) {}
void fun()
{
cout << "A::fun" << value << endl;
}
};
class B :public A
{
public:
void fun()
{
cout << "B::fun" << endl;
}
};
int main()
{
B b;
b.fun(); //调用B中的fun函数
b.A::fun(); //明确告知调用A中的fun函数
system("pause");
return 0;
}
10.只有在同一个类中才有函数重载
同名隐藏
函数重载
11. 赋值兼容规则
在任何需要基类对象的地方都可以用公有派生类的对象代替
公有继承意味着 是一个 的概念 , 比如 学生是一个人 , 不能说 人是一个学生
1) 派生类的对象可以赋值给基类对象,这时是把派生类对象中从对应基类中继承来的隐藏基对象赋值给基类对象
2)可以将一个派生类的对象的地址给其基类的指针变量,但只能通过这个指针访问派生类中由基类继承来的隐藏对象,不能访问派生类中的新成员
3)派生类对象可以初始化基类的引用,但引用只能包含派生类对象中的由基类继承来的隐藏基对象
12. 派生类的构建
13.赋值兼容(切片现象)
只可把派生类赋值给基类,不能把基类赋值给派生类
学生一定是一个人,但人不一定学生
14.派生类的拷贝构造函数,初始化列表不带基类
如果基类中不存在缺省的构造函数,则无法编译通过!
15.派生类的拷贝构造函数,初始化列表带基类
16.初始化过程
此时,基类的隐藏对象已调用基类的构造函数完成初始化了!
17. 派生类赋值函数
#include <iostream>
using namespace std;
class Object
{
private:
int value;
public:
Object(int x = 0) :value(x) { cout << "Create Object: " << this << endl; }
~Object() { cout << "Destroy Object: " << this << endl; }
Object(const Object & obj) :value(obj.value)
{
cout << "Copy Create Object:" << this << endl;
}
Object & operator=(const Object &obj)
{
if (this != &obj)
{
value = obj.value;
}
cout << "Object:: operator=() " << endl;
return *this;
}
};
class Base :public Object
{
private:
int num;
public:
Base(int x = 0) :num(x), Object(x + 10) { cout << "Creat Base: " << this << endl; }
~Base(){ cout << "Destroy Base:" << this << endl; }
Base(const Base & base) :num(base.num),Object(base)
{
cout << "Copy Create Base:" << this << endl;
}
Base & operator=(const Base& base)
{
if (this != &base)
{
*(Object*)this = base; //将this强转为基类型,调用基类的赋值函数
num = base.num;
}
cout << "Base :: operator=() " << endl;
return *this;
}
};
int main()
{
Base base(10);
Base base2(20);
base = base2;
system("pause");
return 0;
}