公有继承与私有继承区别:
公有继承强调是一个的概念,比如:学生是一个人,研究生是一个学生等等。私有继承强调的组成概念,比如:汽车是由发动机以及其他部件组成,而不能说汽车是一个发动机或者发动机是一个汽车。
公有继承:
在公有继承中,存在赋值兼容性规则。可以将派生类的对象赋值给基类的对象或引用,也可以将派生类的地址赋值给基类指针:
class Person
{
private:
int id_num;
public:
Person(int id=0) :id_num(id)
{
}
~Person(){}
void fun_p()
{
cout << "work" << endl;
}
};
class Student : public Person
{
private:
int s_num;
public:
Student(int id=0, int num=0) :Person(id), s_num(num)
{
}
~Student(){}
void fun_s()
{
cout << "study" << endl;
}
};
int main()
{
Student st;
Person p1 = st;
Person& p2 = st;
Person* p3 = &st;
p3->fun_p();
return 0;
}
赋值的时候,会产生切片现象。
只将上半部分赋值给基类对象。相反的,基类对象不允许赋值给派生类对象,因为赋值的时候s_num无法初始化。
拷贝构造与赋值运算符的重载:
拷贝构造函数与赋值运算符重载函数不会被复制到派生类,所以在调用派生类的拷贝构造函数时需要调用基类的拷贝构造函数。需要注意的是:
1.程序设计者在基类和派生类中都没有定义拷贝构造函数C++编器将自动产生按位拷贝的拷贝构造函数,在派生类的拷贝构造函数的初始化表中,加入基类拷贝构造函数的调用,是C++编译器合成的代码;(完成行为的统一)
2.程序设计者在基类中定义拷贝构造函数,而在派生类中没有定义拷贝构造函数;C++编译器将会在派生类中自动产生按位拷贝的拷贝构造函数。并合成代码,调用(关联) 基类的拷贝构造函数
3.程席设计者在基类和派生类中都定义了堵贝构造函数:程序设计者在派生类中,没有指定调用基类的接贝构造函数时。C++编译器合成的代码调用基类的缺省构造函数,如果基类中没有缺省构造函数。合成代码失败。编译错误。
4.程序设计者在基类中没有定义拷贝构造函数 (C++编译器将自动产生按位拷贝的拷贝构造函数)。而在派生类中定义了拷贝构造函数。程序设计者在派生类中,没有指定调用基类的拷贝构造函数时。C++编译器合成的代码调用基类的缺省构造函数,如果基类中没有缺省构造函数
赋值运算符:
1.程序设计者在基类和派生类中都没有重载operator=函数; C++编译器将在基类和派生类中自动产生按位赋值的,重载operator=函数,C++编译器会在派生类的重载赋值函数中,加入基类重载赋值函数的调用,是C++编译器合成的代码; (完成行为的统一) ;
2.程序设计者在基类中定义重载赋值函数,而在派生类中没有定义重载赋值函数;C++编译器将会在派生类中自动产生按位赋值的重载赋值函数。并合成代码,调用(关联) 基类的重载赋值函数
3,程序设计者在基类和派生类中都定义了重载赋值函数:程序设计者在派生类中,没有指定调用基类的重载赋值函数时。C++编译器不会合成调用基类的重载赋值函数的代码。要在派生类的重载赋值函数调用基类的重载赋值函数,程序设计者必须自己加入调用代码。
4.程序设计者在基类中没有定义重载赋值函数 (C++编译器将自动产生按位赋值的重载赋值函数)。而在派生类中定义了重载赋值函数。程序设计者在派生类中,没有指定调用基类的重载赋值函数。C++编译器不会合成调用基类的重载赋值函数的代码。
友元函数并不具有传递性,也不会被继承。