当前位置: 首页 > article >正文

C++学习路线(二十七)

虚基类

菱形继承的重大缺点

#include <iostream>
using namespace std;

class Tel { // 电话类
public:
	Tel() {
		this->number = 0;
	}
protected:
	int number;
};

class FixLine : public Tel { // 固定电话类
};

class MobilePhone : public Tel { // 移动电话类
};
//无线座机
class WirelessLine : public MobilePhone, public FixLine{ // 无线电话类
public:
	void setNumber(int num) {
		this->Tel::number = num;
	}
	int getNumber() {
		return this->Tel::number;
	}


};
int main() {

	return 0;
}

比如说FixLine,继承于Tel MobilePhone也继承于Tel 那么如果调用number 就会报错

这种情况可以使用虚继承和虚基类进行解决。

#include <iostream>
using namespace std;

class Tel { // 电话类
public:
	Tel() {
		this->number = 0;
	}
protected:
	int number;
};

class FixLine : virtual public Tel { // 固定电话类

};

class MobilePhone : virtual public Tel { // 移动电话类

};
//无线座机
class WirelessLine : public MobilePhone, public FixLine{ // 无线电话类
public:
	void setNumber(int num) {
		this->number = num;
	}
	int getNumber() {
		return this->number;
	}


};
int main() {

	return 0;
}

之前的相亲项目的改造

对Girl类和Boy类进行重构:

  1. 抽取出共同的方法和数据成员, 用来构建一个新的基类[父类]
  2. Girl和Boy类修改为从Human类继承,并修改相关代码。

Human.h

#pragma once
#include <string>
class Humans {
public:
    Humans(std::string name, int age) :   name(name), age(age) {}
    int getAge() const;
    std::string getName() const;
    std::string Description() const;
private:
    std::string name;
    int age;
};

Human.cpp

#include "Human.h"
#include "sstream"
Humans::Humans(std::string name, int age)
{
    this->name = name;
    this->age = age;
}
int Humans::getAge() const {
    return age;
}
std::string Humans::getName() const {
    return name;
}
std::string Humans::Description() const {
    std::stringstream ss;
    ss << "Name: " << name << ", Age: " << age;
    return ss.str();
}

boy.h

#pragma once
#include <string>
#include <vector>
#include "../继承/Human.h"
class Girl;

class Boy : public Humans {
public:
	Boy(std::string name, int age, int salary);
	std::string Description() const;
	int getSalary() const;
	bool satisfy(const Girl& other);
	static void inputsBoys(std::vector<Boy>& boys);
private:
	int salary;
};

boy.cpp

#include <sstream>
#include <string>
#include "boy.h"
#include "girl.h"

#define SALARY_FACTOR 0.005

Boy::Boy(std::string name, int age, int salary) : Humans(name, age) , salary(salary) {}
int Boy::getSalary() const {
    return salary;
}
std::string Boy::Description() const {
    std::stringstream ss;
    ss << getName() << "工资" << salary << " 年龄" << getAge();
    return ss.str();
}
void Boy::inputsBoys(std::vector<Boy>& boys) {
    int n = 1;
    std::string name;
    int age;
    int salary;
    while (1) {
        std::cout << "请输入第" << n << "位男孩的信息(输入0结束输入):" << std::endl;
        std::cout << "年龄:" << std::endl;
        std::cin >> age;
        if (age == 0) break;
        std::cout << "姓名:" << std::endl;
        std::cin >> name;
        std::cout << "工资:" << std::endl;
        std::cin >> salary;
        boys.push_back(Boy(name, age, salary));
        n++;
    }
}

bool Boy::satisfy(const Girl& girl) {
    if (girl.getBeauty() >= salary * SALARY_FACTOR) {
        return true;
    }
    else return false;
}

girl.h

#pragma once
#include <iostream>
#include <string>
#include <vector>
#include "../继承/Human.h"
class Boy;

class Girl : public Humans {
public:
	Girl(std::string name, int age, int beauty);
	std::string Description() const;
	int getBeauty() const;
	bool satisfy(const Boy& boy) const;
	static void inputsGirls(std::vector<Girl>& girls);
private:
	int beauty;
};

girl.cpp

#include "girl.h"
#include "boy.h"
#include <string>
#include <sstream>

#define YANZHI_FACTOR 1.1

Girl::Girl(std::string name, int age, int beauty) : Humans(name, age), beauty(beauty) {}
int Girl::getBeauty() const {
    return beauty;
}
std::string Girl::Description() const {
    std::stringstream ss;
    ss << getName() << "颜值" << beauty << " 年龄" << getAge();
    return ss.str();
}
bool Girl::satisfy(const Boy& boy) const {
    if(boy.getSalary() >= beauty * YANZHI_FACTOR) return true;
    return false;
}
void Girl::inputsGirls(std::vector<Girl>& girls) {
    int age;
    std::string name;
    int beauty;
    int n = 1;
    while (1) {
        std::cout << "请输入第" << n << "位女孩的信息(输入0结束输入):" << std::endl;
        std::cout << "年龄:" << std::endl;
        std::cin >> age;
        if (age == 0) break;
        std::cout << "姓名:" << std::endl;
        std::cin >> name;
        std::cout << "颜值:" << std::endl;
        std::cin >> beauty;
        n++;
        girls.push_back(Girl(name, age, beauty));
    }
}

main.cpp不变


常见错误总结

默认访问权限和语法要求

默认访问权限是private

访问权限之后一定要加冒号:

指定为某种访问权限之后, 就一直是这种权限, 除非再次指定为其他权限.

class MyClass{
    void func(); // private
}

类的成员的访问权限, 与继承方式的区别

相同点:都有public,  private, protected

不同点:意义完全不同。

小结:

成员的访问权限:

public,  可以通过外部来访问(通过对象直接访问), 类似于C语言结构体中的成员

private, 只能在内部访问(在这个类的成员函数内访问),但是在子类的内部不能直接访问。

protected, 只能在内部访问,而且可以在子类的内部直接访问。

继承方式:

public, 父类成员, 被继承到子类后,访问权限都不变。

private, 父类成员, 被继承到子类后,访问权限都变为private

protected, 父类成员, 被继承到子类后,public权限的成员,降级为protected, 其他不变。

项目扩展-位图算法

问题:

有很多不重复的整数, 其中最大值不超过40亿, 最小值是0.

要求判断某个指定的整数, 是否在这个集合中.

#include <iostream>
using namespace std;

void init(char* data, int len) {
	unsigned int n = len * 8;
	for (int i = 0; i < n; i++) {
		if (i % 3 == 0) {
			cout << i << " ";
			char* p = data + i / 8;
			*p |= (1 << (i % 8));
		}
	}
	cout << endl;
}

bool check(char* data, int value) {
	char* p = data + value / 8;
	bool ret =  *p & (1 << (value % 8));
	return ret;
}

int main() {
	unsigned int n = 400;
	int len = n / 8 + 1;
	char* data = (char*)malloc(len);
	memset(data, 0, len);
	init(data, len);
	while (1) {
		int value;
		cin >> value;
		if (value == -1) break;
		if (check(data, value)) cout << "1" << endl;
		else cout << "0" << endl;
	}
	free(data);
	return 0;
}

项目练习一-练习一

定义一个类Book, 用来描述新书, 具有以下功能:
查看当前价格.

查看当前的书号

定义一个类SellBook, 用来表示促销的书籍, 要求继承自Book

具有以下功能:

  1. 查看当前折扣
  2. 设置当前折扣
  3. 查看当前的促销价

Book.h

#pragma once
#include <iostream>
#include <string>
class Book {
public:
	Book(float price, std::string isbn);
	~Book();
	float getPrice() const;
	std::string getISBN() const;
protected:
	double price;
	std::string isbn;
};

Book.cpp

#include "Book.h"

Book::Book(float price, std::string isbn) {
    this->price = price;
    this->isbn = isbn;
}

Book::~Book() {

}

float Book::getPrice() const {
    return price;
}
std::string Book::getISBN() const {
    return isbn;
}

SellBook.h

#pragma once
#include "Book.h"
class SellBook : public Book {
public:
	SellBook(float price, std::string isbn, float discount);
	~SellBook();
	float getPrice() const;
	float getDiscount() const;
private:
	float discount;
};

SellBook.cpp

#include "SellBook.h"

SellBook::SellBook(float price, std::string isbn , float discount) : Book(price, isbn), discount(discount){}
SellBook::~SellBook(){}

float SellBook::getPrice() const {
	return price * discount / 10.0;
}
float SellBook::getDiscount() const {
	return discount;
}

main.cpp

#include <iostream>
#include "Book.h"
#include "SellBook.h"
using namespace std;

int main()
{
    Book b1(30, "123-123");
    SellBook sb1(30, "456-456", 5);
    cout << "Book price: " << b1.getPrice() << endl;
    cout << "SellBook price: " << sb1.getPrice() << endl;

    return 0;
}


http://www.kler.cn/a/374938.html

相关文章:

  • webrtc-internals调试工具
  • 巧妙算法之位运算的应用
  • 外网访问 Docker 容器的可视化管理工具 DockerUI
  • vuex - 第一天
  • 【EtherCATBasics】- KRTS C++示例精讲(2)
  • 第三方接口设计注意要点
  • 12. 内存管理
  • 修改Windows远程桌面3389端口
  • 一. nginx学习笔记 又长又臭篇幅
  • Go如何实现自旋锁
  • 【项目小技巧】【C++】 Debug 日志输出 调用者的函数名,所在文件名和行号
  • C语言学,标准库 <string.h>
  • 自适应神经网络架构:原理解析与代码示例
  • 操作系统期中复习第一单元
  • Docker部署教程:打造流畅的斗地主网页小游戏
  • 大数据新视界 -- 大数据大厂之大数据环境下的网络安全态势感知
  • 访问jenkins页面报错
  • 5G三大应用场景中的URLLC
  • 全新大模型框架Haystack,搭建RAG pipeline
  • 从零开始的C++之旅——string类的模拟实现
  • 【Git】Git常用命令
  • (蓝桥杯C/C++)——常用库函数
  • 【Deno运行时】深入解析Deno:下一代JavaScript和TypeScript运行时
  • cisco网络安全技术第4章测试及考试
  • 高效扶贫:SpringBoot精准扶贫系统
  • 笔记整理—linux驱动开发部分(4)驱动框架