-
多重继承:一个基类派生出一个类,再用派生出的这个类作为基类,派生下一个派生类,依次往下
多继承:一个派生类继承自多个基类
查看全部 -
#include <iostream>
#include <stdlib.h>
#include <string>
using namespace std;/**
* 定义工人类: Worker
* 数据成员: m_strName
* 成员函数: work()
*/
class Worker
{
public:
Worker(string name)
{
m_strName = name;
cout << "Worker" << endl;
}
~Worker()
{
cout << "~Worker" << endl;
}
void work()
{
cout << m_strName << endl;
cout << "work" << endl;
}
protected:
string m_strName;
};/**
* 定义儿童类: Children
* 数据成员: m_iAge
* 成员函数: play()
*/
class Children
{
public:
Children(int age)
{
m_iAge = age;
cout << "Children" << endl;
}
~Children()
{
cout << "~Children" << endl;
}
void play()
{
cout << m_iAge << endl;
cout << "play" << endl;
}
protected:
int m_iAge;
};/**
* 定义童工类: ChildLabourer
* 公有继承工人类和儿童类
*/
class ChildLabourer :public Worker,public Children
{
public:
ChildLabourer(string name, int age):Worker(name),Children(age)
{
cout << "ChildLabourer" << endl;
}~ChildLabourer()
{
cout << "~ChildLabourer" << endl;
}
};int main(void)
{
// 使用new关键字创建童工类对象
ChildLabourer *p = new ChildLabourer("xiaohu",12);
// 通过童工对象调用父类的work()和play()方法
p->work();
p->play();
// 释放
delete p;
p = NULL;return 0;
}查看全部 -
#include <iostream>
#include <stdlib.h>
#include <string>
using namespace std;/**
* 定义人的类: Person
* 数据成员姓名: m_strName
* 成员函数: eat()
*/
class Person
{
public:
string m_strName;
void eat()
{
cout << "eat" << endl;
}
};/**
* 定义士兵类: Soldier
* 士兵类公有继承人类: public
* 数据成员编号: m_strCode
* 成员函数: attack()
*/
class Soldier:public Person
{
public:
string m_strCode;
void attack()
{
cout << "fire!!!" << endl;
}
};int main(void)
{
// 创建Soldier对象
Soldier sor;
// 给对象属性赋值
sor.m_strName = "Jim";
sor.m_strCode = "592";
// 打印对象属性值
cout << sor.m_strName << endl;
cout << sor.m_strCode << endl;
// 调用对象方法
sor.attack();
sor.eat();return 0;
}查看全部 -
私有继承后父类对象的public和protected成员被继承到子类的private下,类似于在子类中定义了一个父类的私有对象成员。这两种方式都被称为has-a
查看全部 -
无论何种继承方式,子类都不可访问父类的私有成员
查看全部 -
当父类与子类有同名变量或函数时,通过子类对象直接调用的是其自身的成员变量或函数;子类对象可以通过加父类名的方式访问父类变量及函数。例如soldier.Person::m_strName;
soldier.Person::attack();
查看全部 -
派生类的对象可以赋值的基类,而基类的对象不能赋值给派生类
Soldier s1; Person p1=s1; Person *p2=&s1;//这三行是正确的 s1=p1; Soldier *s2=&p1;//这两行是错误的
对于作为函数参数时:
void fun(Person *p){...} int main(){ Person p1; Soldier s1; fun(&p1); fun(&s1);//这两种都是正确的 }
用子类对象初始化父类对象时,从父类中继承下来的属性会被初始化,而子类中特有的属性则会被截断(不会赋值给父类)
查看全部 -
control + k + c——多行注释
control + k + u——解除多行注释
查看全部 -
"isA":是共有继承下的子类与父类之间的关系。
概念上,子类也是父类,可以利用子类对父类进行实例化,初始化,赋值等操作。但反过来不可。销毁父类时引入virtual虚析构函数。
(1)当一个子类的对象去初始化或者对一个父类的对象赋值时,本质上就是把子类从父类所继承下的数据成员赋值给父类的原有的数据成员,此时子类对象的其他数据成员就会丢失
(2)若是父类的一个对象指针指向一个子类的对象,则访问,也只能访问到从父类继承下来的数据成员。(本质上都是在访问自己数据成员所在的内存空间,人为概念上区分了,但是硬件本质上操作的还是同一块内存区域)
//Person为父类,Worker为子类 Person *p=new Worker; p->eat(); delete p; p=NULL//只是释放Person类,可能会造成worker类内存泄漏
(1)用子类实例化父类时,先调用父类构造函数,再调用子类构造函数
(2)销毁时只释放父类内存,可能造成子类内存的泄露,因此,引入virtual虚析构函数,virtual可以继承下去,即便子类中不写该关键字也是虚析构函数,这样在销毁父类时,会先销毁子类,再销毁父类。
“has a”代表的是对象和它的成员的包含关系。c++还有另一种实现has-a关系的途径----私有继承。使用私有继承,基类的公有成员和保护成员都将成为派生类的私有成员。这意味着基类方法将不会成为派生对象公有接口的一部分,但可以在派生类的成员函数中使用它们。因此私有继承提供的特性与包含相同:获得实现,但不获得接口。所以,私有继承也可以用来实现has-a关系。
查看全部 -
实例化子类时,会先调用父类的构造函数,再调用子类自己的构造函数。 析构时,先调用自己析构的函数,再调用父类的析构函数。查看全部
-
这一节有碎的常见报错知识
查看全部 -
首先他证明了protected继承并不是被继承到public里面,因为person的子类Soldier的实例无法访问protected继承自person的数据成员,这时还有可能是被继承到private里面;但是,Soldier的子类Infantry可以访问到父类protected继承自person的成员函数,说明只能是被继承到protected中,若是到了private中,则Infantry中无法使用。
外部调用(如主函数中直接调用)只能调用public里的成员及函数。
内部成员函数(在同一个类里面)却可以调用包括其本身的public、protected、private内成员。
查看全部 -
类的析构函数使用多态性(动态绑定)时,需要申明为虚函数。保证在delete释放基类指针(指向子类)释放资源时,即释放基类资源也释放派生类资源。不使用虚函数,会导致析构不完整,这种情况下delete基类指针只会调用父类的析构函数,从而不能释放子类的资源。
查看全部 -
注:使用虚继承时虽然不会重复调用最顶层父类,但参数只能使用最顶层父类默认值,而不能读入子类设置值
查看全部 -
扩展探索:只有其中一个虚继承时,执行顺序有什么变化呢?
结果:最终子类优先执行虚继承的基类的构造函数,然后再按正常顺序调用各构造函数(此时虚继承的就不用执行了)
查看全部
举报