子类型关系
1. 含义
含义
公有继承时,子类的对象可以作为基类的对象处理,子类是基类的子类型
子类型关系有单向传递性,C类是B类的子类型,B是A的子类型,那么C也是A的子类型
class A{
public:
void kill(){
cout << "A kill empety" << endl;
};
};
class B : public A{
public:
void kill(){
cout << "B kill empety" << endl;
}
};
void test(A a){
a.kill();
}
int main(){
B b;
test(b);
return 0;
}
2. 作用
当函数的形参类型为基类,实参可以用子类对象作为实参
3. 应用
-
基类(父类)的指针,可以指向这个类的公有派生类(子类型)对象。
Son son;
Father * f = &son;
-
公有派生类(子类型)的对象可以初始化基类的引用
Son son;
Father &f2 = son;
-
公有派生类(子类型)的对象可以赋值给基类的对象
Son son;
Father f1 = son;
多重继承
1. 含义
一个派生类继承两个或多个基类
2. 用法
多个基类之间用 , 隔开
class D: public A, private B, protected C{
//类D自己新增加的成员
};
3. 构造函数
继承多个父类的派生类的构造函数的实现与单继承一致
D::D(形参列表):A(实参列表),B(实参列表),C(实参列表){
//...
//...
}
4.弊端
当子类继承的多个父类中存在相同方法,当子类对象调用这一方法时,编译器会报错,不知道该调用哪一个
解决方法:
① 子类调用时指定是哪一个基类中的方法
② 在子类中重新定义方法,使用子类对象直接调用
class A{
public:
void method(){
prinf("A类中的方法...\n");
}
};
class B{
public:
void method(){
prinf("B类中的方法...\n");
}
}
class C : public A, public B{
//....
//重新定义方法
void method(){
prinf("C类中的方法...\n");
}
}
C c;
c.method(); //系统报错,不知道调用哪一个method方法
//指定哪一个基类只中的方法
c.A::method();
c.B::method();
c.method(); //使用子类对象直接调用
虚基类
当两个派生类继承自同一个类,同时这两个派生类同时被另一个派生类多重继承,这个派生类中的访问继承来的数据成员时会发生错误,无法确定是访问哪个数据成员
class Tel{
public:
Tel();
protected:
string number;
};
class FixPhone : public Tel{}
class MobilePhone : public Tel{}
class WirelessTel : public FixPhone, public MobilePhone{
public:
WirelessTel(){}
void setNumber(stirng *number){
this.number = number; //报错,不知道是哪个父类中的number
}
string getNumber(){
return number; //报错,不知道是哪个父类中的number
}
}
解决方法:
① 在派生类中指定是哪个父类中的数据成员
class Tel{
public:
Tel();
protected:
string number;
};
class FixPhone : public Tel{}
class MobilePhone : public Tel{}
class WirelessTel : public FixPhone, public MobilePhone{
public:
WirelessTel(){}
void setNumber(stirng *number){
this->FixPhone::number = number; //指定是哪个父类中的数据成员
}
string getNumber(){
return FixPhone::number; //指定是哪个父类中的数据成员
}
}
② 采用虚继承的方式,在继承方式前加上virtual
class Tel{
public:
Tel();
protected:
string number;
};
class FixPhone :virtual public Tel{}
class MobilePhone :virtual public Tel{}
class WirelessTel : public FixPhone, public MobilePhone{
public:
WirelessTel(){}
void setNumber(stirng *number){
this->number = number;
}
string getNumber(){
return number;
}
}
位图算法
问题:
有很多不重复的整数, 其中最大值不超过40亿, 最小值是0.
要求判断某个指定的整数, 是否在这个集合中
解决方案:
采用位图算法,用空间换取时间
[例] 使用2个字节,即16位来表示16个数的状态
若需要的数据为【5,1,7,15,0,4,6,10】那么对应的存储状态为:
需要用到这些数据时只需要查找状态为1的位置来访问
代码实现
#include <iostream>
void initValue(char *data, int len){
// char *p = data;
char *p;
unsigned int n = len*8;
for(unsigned int i=0; i<n; i++){
if(i%3 == 0){
p = data + i/8;
*p = *p |1<<(i%8);
}
}
}
bool judgeValue(char *data, int value){
char *p = data + value/8; //第幾個字節
/* if(*p & (1<<(value%8))){
return true;
}else{
return false;
} */
return *p & (1<<(value%8));
}
int main(){
long long value = 4000000000;
int len = value/8 + 1;
char *p;
p = new char[len];
memset(p,0,len);
initValue(p,len);
int inputValue;
while(1){
std::cout << "去請輸入值【輸入-1結束】:" << std::endl;
std::cin >> inputValue;
if(inputValue == -1){
break;
}
if(judgeValue(p,inputValue)){
std::cout << inputValue << "是滿足的數據" << std::endl;
}else{
std::cout << inputValue << "是不符合的數據" << std::endl;
}
}
delete[] p;
return 0;
}