C++一周学习总结(2021/03/14)

子类型关系

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. 应用

  1. 基类(父类)的指针,可以指向这个类的公有派生类(子类型)对象。
    Son son;
    Father * f = &son;

  2. 公有派生类(子类型)的对象可以初始化基类的引用
    Son son;
    Father &f2 = son;

  3. 公有派生类(子类型)的对象可以赋值给基类的对象
    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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值