类的继承:
1,类与类之间的关系:1>包含关系:类作为数据成员
2>一个类部分使用另一个类的数据成员和方法,通过定义友元
3>继承:传递关系,继承包含单继承和多继承
2.继承的分类:
1>公有继承: 基类的公有成员——>派生类的公有成员。继承方式 A:public B{};
基类的保护成员——>派生类的保护成员
公有继承可以无限传承
2>私有继承:基类的公有成员和保护成员——>派生类的私有成员 A:private B{};
私有继承只可以继承一次
3>保护继承:基类的公有成员和保护成员——>派生类的保护成员A:protected B{};
保护继承可以无限继承。
注意:无论通过那种继承,派生类都不可以访问基类的私有成员。且类的构造顺序是:父类->子类->孙类(析构顺序相反)
继承中如果出现成员函数重名,子类覆盖父类的成员函数,可以通过继承实现迭代式开发。
#include<iostream>
class fulei
{
public:
fulei();
~ fulei();
int z = 3;
void print()
{
std::cout << x << ' ' << y << std::endl;
}
private:
int x;
int y;
protected:
void setxy(int a, int b)
{
this->x = a;
this->y = b;
};
};
fulei:: fulei()
{
this->x = 1;
this->y = 2;
}
fulei::~ fulei()
{
}
class zilei:public fulei
{
public:
void jicheng() //调用公有成员和保护成员
{
setxy(100, 200);
print();
}
private:
};
//公有继承,单继承
void main1()
{
zilei zilei1;
zilei1.print();
zilei1.jicheng();
std::cin.get();
}
void main2()
{
fulei *pfulei = new zilei;
pfulei->print();
zilei *pzilei = reinterpret_cast<zilei *>(pfulei);
pzilei->jicheng();
std::cin.get();
}
3.通过派生类对基类进行初始化。
#include<iostream>
class myclass
{
public:
myclass() :x(0)
{
std::cout << "初始化10";
}
myclass(int num) :x(num)
{
std::cout << "初始化11";
}
protected:
private:
int x;
};
class myzi :public myclass
{
public:
myzi()
{
std::cout << "初始化20";
}
myzi(int num) :myclass(num),x(num),y(num)
{
std::cout << "初始化21";
}
int x;
int y;
};
void main4()
{
myzi *pc1=new myzi;
myzi *pc2 = new myzi(100);
std::cin.get();
}
4.类继承静态数据成员
#include<iostream>
class myclass
{
public:
int data=0;
static int num;
myclass()
{
num++; //计数位于静态区
}
static void print()//静态函数无法使用this指针
{
std::cout << num << std::endl;
}
private:
};
int myclass::num = 0;
class ziclass :public myclass
{
public:
};
class sunclass :public ziclass
{
};
class zi1class :private myclass
{
public:
void run()
{
this->print();
this->num;
}
};
void main3()
{
ziclass *p = new ziclass;//创建子类对象,会创建基类对象
ziclass z2;
sunclass *ps = new sunclass;
p->num;
p->print();
ps->ziclass::myclass::print();
zi1class cc;
cc.run();
std::cin.get();
}
5.多继承
多继承派生类的构造与访问
1>拥有多个基类的继承的派生类的构造函数可以用初始化方式调用基类的构造函数初始化基类的数据成员
2>多个基类构造函数的执行顺序取决于继承顺序
3>基类的重名方法在调用时应该加以说明
#include<iostream>
#include<stdlib.h>
class A
{
};
class B
{
};
class class1
{
public:
void run(char *str)
{
system(str);
}
class1()
{
std::cout << "class1 build"<<std::endl;
}
~class1()
{
std::cout << "class1 ruin"<<std::endl;
}
private:
};
class class2
{
public:
int add(int a, int b)
{
return a + b;
}
class2()
{
std::cout << "class2 build"<<std::endl;
}
~class2()
{
std::cout << "class2 ruin" << std::endl;
}
};
class my :public class1, public class2,public A,public B
{
public:
void print(char *str)
{
std::cout << str << std::endl;
}
my()
{
std::cout << "my build" << std::endl;
}
~my()
{
std::cout << "my ruin" << std::endl;
}
};
void run()
{
my m1;
std::cout << m1.add(100, 200) << std::endl;
m1.run("tasklist");
m1.class1::run("ipconfig");
m1.print("123456");
}
void main()
{
run();
std::cin.get();
}
6.虚基类
一个派生类继承了两个基类,而这两个基类派生于同一个基类,在继承的路径的汇合点处,公共基类将在派生的对象中产生多个基类对象,想要只产生一个子对象,需声明为虚继承,使基类成为虚基类。
#include<iostream>
//虚基类
class obj
{
public:
int num=0;
obj()
{
std::cout << "obj creat\n";
}
obj(int data):num(data)
{
std::cout << "obj creat\n";
}
~obj()
{
std::cout << "obj delete\n";
}
};
class obja :virtual public obj
{
public:
obja()
{
std::cout << "obja creat\n";
}
obja(int data):obj(data)
{
std::cout << "obja creat\n";
}
~obja()
{
std::cout << "obja delete\n";
}
};
class objb :virtual public obj
{
public:
objb()
{
std::cout << "objb creat\n";
}
objb(int data):obj(data)
{
std::cout << "objb creat\n";
}
~objb()
{
std::cout << "objb delete\n";
}
};
class objab :public obja, public objb
{
public:
objab()
{
std::cout << "objab creat\n";
}
objab(int a):obja(a),objb(a) //值的传递
{
std::cout << "objab creat\n";
}
~objab()
{
std::cout << "objab delete\n";
}
};
void run()
{
objab c1(10);
std::cout << c1.obja::num;//出现歧义,需进行说明
std::cout << c1.objb::num;
}
void main()
{
run();
//objab *p = new objab(10);
//delete p;
std::cin.get();
}