继承方式
/*默认继承方式为private
(1)public继承时
- 父类的public成员,变为子类的public成员
- 父类的protected成员,变为子类的protected成员
- 父类的private成员,变为子类不可直接使用的成员
(2)private继承时
- 父类的public成员,变为子类的private成员
- 父类的protected成员,变为子类的private 成员
- 父类的private成员,变为子类不可直接使用的成员
(3)protected继承时
- 父类的public成员,变为子类的protected成员
- 父类的protected成员,变为子类的protected成员
- 父类的private成员,变为子类不可直接使用的成员
基类的public成员,相当于派生类的private成员,无论何种继承,父类的private成员不允许子类成员访问!
!!!当父类的成员被声明为protected,则子类可以访问,而子类实例化的对象不可以访问 。
继承方式调整
class B: private A
{
public:
A::f1;把A中f1函数调整为public
};
派生类对象的初始化
class A
{
int x;
public:
A(){x = i;}
A(int i) {x = i;}
};
class B: public A
{
int y;
public:
B(int i)
{
y = i;
}
B(int i, int j):A(i)
{
y = j;
}
};
B b1(1); //调用A()和B(int i)
B b2(1, 2);//调用A(int)和B(int i, int j)
例子-单继承
#include <iostream>
#include <string>
using namespace std;
class Employee
{
string name;
int salary;
public:
Employee(const char *s, int n=0):name(s)
{
salary = n;
}
void set_salary(int n){salary = n;}
int get_salary() const {return salary;}
string get_name() const {return name;}
};
const int MAX_MUN_OF_EMPS = 20;
class Manager: public Employee
{
Employee *group[MAX_MUN_OF_EMPS];
int num_of_emps;
public:
Manager(const char *s, int n=0):Employee(s,n)
{
num_of_emps = 0;
}
Employee *add_employee(Employee *e)
{
if(num_of_emps >= MAX_MUN_OF_EMPS) return NULL;
group[num_of_emps] = e;
num_of_emps++;
return e;
}
};
int main()
{
Employee e1("jack", 1000),e2("john", 2000);
Manager m("boss", 4000);
m.add_employee(&e1);
cout<<m.get_name()<<endl;
cout<<m.get_salary()<<endl;
return 0;
}
多态,动态绑定
C++中把以public方式继承的派生类看做基类的子类型。
class A;
class B: public A
A a, *p;
B b, *q;
b.f();
p = &b;//父类指针可以指向派生类对象
a = b;//用b对象改变a的状态,属于B但不属于A的数据忽略
- C++一般采取静态绑定,即根据已经定义的参数类型f(A *p)中A类型决定调用A中f( )。不会根据传入的参数是A,或B而动态选择调用哪个函数的f( )。实现动态绑定则需要把A类中f()函数定义为虚函数。
- 虚函数的动态绑定即,派生类中定义的相同函数对基类成员函数的重定义。只有采用指针或引用来访问对象的虚函数才进行动态绑定。
class A
{
public:
f();
};
class B: public A
{
public:
f();
};
void f(A *p){p->f();}
void g(A& a){a.f();}
A a;
B b;
f(&a);//调用A中f
f(&b);//调用A中f
----------
class A
{
public:
virtual void f();
};
class A
{
public:
virtual void f();
};
class B: public A
{
public:
void f();
void g();
};
A *p = new B;
p->f();
p->g();//出错,A中没有g()
((B *)p)->g();//可以,调用B中g
B *q;
q = dynamic_cast<B *>(p);// dynamic_cast转换指针p,若 A *p = new A;则转换失败返回NULL
纯虚函数和抽象类
纯虚函数只给出函数声明,没有定义,在函数原型后面加“=0”。包含纯虚函数的类定义为抽象类,抽象类不能用于创建对象,他用于给派生类提供一个基本框架和公共函数的对外接口。
class A
{
public:
virtual void f()=0;
};
重复继承-虚基类
B、C都继承了A,所以当D继承B和C时需要合并重复的A
class B: virtual public A
class C: virtual public A
class D: public B, public C