c++数据结构与算法【adam drozdek】通关日记1

本文介绍了面向对象编程的基础概念,如在VS2022环境下使用Java和C++进行OOP,涉及封装、继承、抽象数据类型和C++标准模板库(STL)。作者分享了如何在C++中处理字符串和数据类型,以及类的封装和继承实例。
摘要由CSDN通过智能技术生成

学习目标:学习此书u1【不包含后面编程练习和案例分析】


unit1 面向对象程序设计
使用软件:vs 2022


学习内容:

单元:unit1 面向对象程序设计OOP 使用软件:vs 2022

  1. 搭建 Java 开发环境
  2. 封装
  3. 继承
  4. 指针
  5. 多态
  6. c++面对对象程序设计
  7. 标准模板库
  8. 标准模板库的向量
  9. 数据结构与面向对象编程

学习时间:

2023/11/15 完成1,2,3节

预计:
2023/11/16 完成4,5,6节
2023/11/17 中断去补课“黑马程序员的函数模板部分”
2023/11/18 中断去补课”黑马程序员的STL部分“
2023/11/19 完成7,8,9节


1.抽象数据类型

提示:这里统计学习计划的总量
指定了操作的项被称为抽象数据类型ADT
然而,诸如C++之类的面向对象语言(OOL)与抽象数据类型有着直接的联系,
这种语言将OOL作为一个类来实现。


2.封装

对象是用类定义,类是一个模板,包括操作(函数或者方法)、数据成员
数据及其相关操作的结合称为对数据的封装
对象是类的实例,是用类定义创建的实体
封装的特点:
类内成员结合紧密(强耦合)
对象操作的有限原则(减少错误)
信息隐藏原则(对象)
提示:这里有示例代码
原代码:

class C {
public:
	C( char*s="",int i, double d) {
		//报错1:参数列表char*s=""
		strcpy(dataMember1, s);
		//报错2:strcpy不安全
		dataMember2 = i;
		dataMember3 = d;
	}
	void memberFunction1() {
		cout<< dataMember1  << ' ' << dataMember2 << ' ' <<
			dataMember3 << endl;
	}
	void memberFunction2(int i, char* s = "unkown") {
		//报错5:同报错1
		dataMember2 = i;
		cout << i << "received from" << s << endl;
	}
protected:
	char dataMember1[10];
	int dataMember2;
	double dataMember3;
};

C object1("object1",100,200);
//报错3:"object1"类型与参数不符
C object2("object2");
C object3;
//报错4:类的声明需要括号

改法1

class C1 {
public:
	C1(const char* s1, int i, double d) {

		//原代码:
		// 参数列表原本为char*s=""
		// 是不可以这么做的,并且指向的是一个字符串
		//【其实是字符型数组】不可更改,类型是const char *


		// strcpy(dataMember1,s)
		// 将s复制给数据成员1
		// 但strcpy不安全且找不到有效解决方案
		// 并且在创建对象时传入参数char*s=""为字符串"object1"
		// 也不符合

		// 字符串就是数组,在参数前面加const之后
		// 可以通过下标赋值给数据成员1数组值
		for (int i = 0; i < sizeof(s1); i++) {
					dataMember1[i] = s1[i];
		
				}

		dataMember2 = i;
		dataMember3 = d;
	}
	void memberFunction1() {
		cout << dataMember1 << ' ' << dataMember2 << ' ' <<
			dataMember3 << endl;
	}
	void memberFunction2(int i, const char* s ) {
		// 改参数类型即可
		dataMember2 = i;
		cout << i << "received from" << s << endl;
	}

protected:
	char dataMember1[10];
	int dataMember2;
	double dataMember3;
};
C1 object1("object1",100,200);
C1 object2("object2");
C1 object3();

改法2

class C2 {
public:
	C2( string s1, int i, double d) {
		
		//原代码:
		// 参数列表string s1处原本为char*s=""
		
		// 新建对象时传入s1是一个字符串,则直接改为字符串
		
		//string类内有一个函数是c_str就是返回
		//当前字符串的首字符地址,其实也是一个数组
		//就for循环直接下标赋值就好了

		for (int i = 0; i < sizeof(s1); i++) {
			dataMember1[i] = s1.c_str()[i];
		}
		dataMember2 = i;
		dataMember3 = d;
	}
	void memberFunction1() {
		cout<< dataMember1  << ' ' << dataMember2 << ' ' <<
			dataMember3 << endl;
	}

protected:
	char dataMember1[10];
	int dataMember2;
	double dataMember3;
};

C++的强大特性之一是能够在类声明中使用类型参数来声明通用类。例如,如果需要声明一个使用数组存储数据的类,可以将该类声明为:

class intsto {
private:
	int storage[50];
};

然而这种方式使得这个类仅适用于整数。如果一个类需要执行与intClass相同的操作,但操作的是浮点数或其他类型的数据等等,就需要声明新类。

更好的方法是声明一个通用类,只有在定义对象时才会确定对象引用什么类型的数据。幸运的是,C++允许以这种方式声明类,下面是这种类声明的示例:
提示:此处拓展一下模板的知识

template<class genType>
//声明类模板名 genType
class genClass {
public:
	genType storage[50];
};

我们可以更进一步,可以不将 storage 数组的大小确定为50个单元,
而是将这个决定推迟到对象的定义阶段。
但是为了防止意外也可以使用一个默认值,所以可以将类声明为:

template<class genType,int size=50>
class genClass2 {
public:
	genType storage[size];
};

这种使用通用类型的方法并不局限于类;在函数声明时同样适用。
eg。交换两个数值的函数
这里也是错的用于函数的模板不应该这样声明
template

template<typename genType>
void swap1(genType & i1, genType & i2) {
	genType temp = i2;
	i2 = i1;
	i1 = temp;
}

这个示例还说明内置的运算符只能应用于特定的场合。
如果 genType是一个数值、一个字符或者是一个结构,
那么“ = ”号会正常地执行其功能。
但是如果genType是一个数组,swap就会遇到问题,为了解决这个问题,
可以重载赋值运算符, 在该运算符中加入特定数据类型所需要的功能。
在声明了通用函数之后,在编译期间,编译器会生成一个适当的函数。
例如:main函数中的调用

int a = 1;
int b = 2;
swap1<int>(a, b);
float c = 12.17;
float d = 3.14;
swap1(c, d);

3.继承

书上示例代码修改版及笔记

其中类内函数的参数原本都为char ,都改为const char

class BaseClass {
public:
	BaseClass(){}
	void pu(const char*s) {
		cout << "pu() in baseClass called from " << s << endl;
	}
protected:
	void pro(const char* s) {
		cout << "pro() in baseClass called from " << s << endl;
	}
private:
	void pri() {
		cout << "pri() in baseClass called from " << endl;
	}

};
class SonClass1 :public virtual BaseClass {
public:
	void pu(const char* s) {
		cout << "pu() in son1 called from " << s << endl;
		pro("son1");
		pri("son1");
		
	}
	void pri(const char*s) {
		cout << "pri() in son1 called from " << s << endl;
	}
 };
class SonClass2 :public virtual BaseClass {
public:
	void pu(const char* s) {
		cout << "pu() in son2 called from " << s << endl;
		pro("son1");
		//pri("son1");
		//报错因为父类private内容不可以访问
	}
};
class Grandson : public SonClass1, public SonClass2 {
public:
	void pu(const char* s) {
		cout << "pu() in grandson called from " << s << endl;
		pro("grandson");
		SonClass1::pro("grandson");
		BaseClass::pu("grandson");
	
	}

 };

//main函数代码
BaseClass papa;
SonClass1 son1;
SonClass2 son2;
Grandson grandson;
papa.pu("main(1)");
//父类protected和private类外都不可以访问
son1.pu("main(2)");
son1.pri("main(3)");
//son1在自己类内public重写的pu和pri类外都可以调用
//且pu函数内可调用继承的protected的pro函数,
//注意这里调用的pri是重写的,不是父类原本在private内的pri函数
son2.pu("main(4)");
//son2在自己类内public重写的pu类外可以调用
//且pu函数内可调用继承的protected的pro函数,
grandson.pu("main(5)");
//grandson在类外可以访问在public重写的pu函数,
//并在其中调用继承的在protected内的pro函数
//加上类的作用域还可以在类内访问到父类的public和protected的函数



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值