C++面向对象程序设计-北京大学-郭炜【课程笔记(二)】

2024-02-17 10:28

本文主要是介绍C++面向对象程序设计-北京大学-郭炜【课程笔记(二)】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

C++面向对象程序设计-北京大学-郭炜【课程笔记(二)】

  • 1、结构化程序设计
    • 结构化程序设计的不足
  • 2、面向对象的程序设计
    • 2.1、面向对象的程序设计
    • 2.2、从客观事物抽象出类
    • 2.3、对象的内存分配
    • 2.4、对象之间的运算
    • 2.5、使用类的成员变量和成员函数
      • `用法1:对象名.成员名`
      • `用法2:指针->成员名`
      • `用法3:引用.成员名`
    • 2.6、类成员的可访问范围
      • 2.6.1、代码实例
      • 2.6.2、private的意义(隐藏的作用)
      • 2.6.3、成员函数的重载及参数缺省

课程链接:程序设计与算法(三)C++面向对象程序设计 北京大学 郭炜
课程PPT:github提供的对应课程PPT

1、结构化程序设计

C语言使用结构化程序设计:
程序 = 数据结构 + 算法

  • 程序由全局变量以及众多相互调用的函数组成。
  • 算法以函数的形式实现,用于对数据结构进行操作。

结构化程序设计的不足

  • 结构化程序设计中,函数和其所操作的数据结构,没有直观的联系。
  • 随着程序规模的增加,程序逐渐难以理解,很难一下子看出来:
    • 某个函数结构到底有哪些函数可以对他进行操作?
    • 某个函数到底是用来操作哪些数据结构的?
    • 任何两个函数之间存在怎样的低哦啊用关系?
    • 结构化程序设计没有“封装”和“隐藏”的概念。要访问某个数据结构中的某个变量,就可以直接访问,那么当该变量的定义有改动的时候,就要把所有访问该变量的语句找出来修改,十分不利于程序的维护、扩充。
    • 难以查错,当某个数据结构的值不正确时,难以找出到底是哪个函数导致的。
    • 结构化程序设计中,随着程序规模的扩大,由于程序大量函数、变量之间的关系错综复杂,要抽取这部分代码,变得十分困难(无法重用)。

2、面向对象的程序设计

  • 面向对象的程序设方法,能够较好的解决上述结构化程序设计的不足。
    面向对象的程序 = 类 + 类 + ···· + 类
  • 设计程序的过程,就是设计类的过程。

2.1、面向对象的程序设计

面向对象的程序设计方法:

  • 将某类客观事物共同特点(属性)归纳出来,形成一个数据结构(可以用多个变量描述事物的属性);
  • 将这类事物所能进行的行为也归纳出来,形成一个个函数,这些函数可以用来操作数据结构(这一步叫“抽象”)。

然后,通过某种语法形式,将数据结构和操作该数据结构的函数“捆绑”在一起,形成一个“”,从而使得数据结构和操作该数据结构的算法呈现出显而易见的紧密关系,这就是“封装”。

面向对象的程序设计具有“抽象”,“封装”,“继承”,“多态”四个基本特点。

面向对象的程序模式:(如下图所示)
在这里插入图片描述

2.2、从客观事物抽象出类

在这里插入图片描述

  • 将长、宽变量和设置长、宽,求面积,以及求周长的三个函数“封装”在一起,就能形成一个‘矩形类’。
  • 长、宽变量成为该“矩形类”的“成员变量”,三个函数成为该类的“成员函数”。成员变量和成员函数统称为类的成员。

代码:

#include <iostream> class CRectangle
{public:int w, h;   // 成员变量// 三个成员函数int Area() {return w * h;}int Perimeter() {return 2 * (w + h);}void Init(int w_, int h_) {w = w_; h = h_;}
};   //必须有分号int main()
{int w,h;CRectangle r;  // r是一个对象std::cout << "请输入w和h"<<std::endl;std::cin >> w >> h;r.Init(w, h);std::cout << r.Area() << std::endl << r.Perimeter();return 0;
}//OUT:
请输入w和h
1
3
面积 = 3; 周长 = 8

通过类,可以定义变量。类定义出来的变量,也称为类的实例,就是我们所说的“对象”
C++中,类的名字就是用户定义的类型的名字。可以像使用基本类型那样来使用它。CRectangle就是一种用户自定义的类型。

2.3、对象的内存分配

  • 和结构变量一样,对象所占用的内存空间的大小,等于所有成员变量的大小之和。
  • 对于上面的CRectangle类,sizeof(CRectangle) = 8
    • 成员函数会占用存储空间,但是一个类的成员函数在内存中只有一份,他被所有对象所共享,成员函数不会放入到对象里面。(对象只包含成员变量,不包含成员函数。)
  • 每个对象各有自己的存储空间。一个对象的某个成员变量被改变了,不会ing下昂另一个对象。

2.4、对象之间的运算

和结构变量一样,对象之间可以用 “=” 进行赋值,但是不能用“==”,“!=”,“<”,“>=“,”<=“,进行比较,除非这些运算符经过了“重载”。

2.5、使用类的成员变量和成员函数

用法1:对象名.成员名

CRectangle r1, r2;
r1.w = 5;
r2.Init(5, 4);

Init函数作用在r2上,即Init函数执行期间访问的w和h是属于r2这个对象的,执行r2.Init不会影响到r1。

用法2:指针->成员名

CRectangle r1,r2;
CRectangle * p1 = & r1;
CRectangle * p2 = & r2;
p1->w = 5;
p2->Init(5,4);  //Init作用在p2指向的对象上

用法3:引用.成员名

CRectangle r2;
CRectangle & rr = r2;
rr.w = 5;
rr.Init(5,4);  // rr的值变了,r2的值也会随着改变void PrintRectangle(CRectangle & r)
{cout << r.Area() << "," << r.Perimeter();
}
CRectangle r3;
r3.Init(5,4);
printRectangle(r3);

2.6、类成员的可访问范围

在这里插入图片描述
在这里插入图片描述

2.6.1、代码实例

#include <iostream> 
#include <stdio.h>
// #include <string.h>class CEmployee { private:char szName[30]; //名字public :int salary; //工资void setName(char * name); void getName(char * name);void averageSalary(CEmployee e1,CEmployee e2);
};void CEmployee::setName( char * name) {strcpy(szName, name); //ok
}
void CEmployee::getName( char * name) {strcpy(name, szName); //ok
} 
void CEmployee::averageSalary(CEmployee e1,CEmployee e2){salary = (e1.salary + e2.salary )/2;
}int main(){CEmployee e;// strcpy(e.szName,"Tom1234567889"); //编译错, 不能访问私有成员e.setName("Tom"); // oke.salary = 5000; //okreturn 0;
}

知识点扩充:C语言中字符串之间的比较【char*】/【string】

2.6.2、private的意义(隐藏的作用)

  • 设置私有成员的机制,叫“隐藏”
  • 隐藏”的目的是强制对成员变量的访问一定要通过成员函数进行,那么以后成员变量的类型等属性修改后,字需要更改成员函数即可。否则,所有直接访问成员变量的语句都需要修改。
  • 如果上面的程序移植到内存空间紧张的手持设备上,希望将szName改为char szName[5],若szName不是私有,那么就要找出所有类似strcpy(e.szName, "Tom1234567889");,这样的语句进行修改,以防止数组越界。这样做很麻烦。
  • 如果将szName变为私有,那么程序中就不可能出现(除非在类的内部)strcpy(e.szName, "Tom1234567889");这样的语句,所有对szName的访问都是通过成员函数来进行,比如:e.setName("Tom"); ,那么,就算szName改短了,上面的语句也不需要找出来修改,只要改setName成员函数,在里面确保不越界就可以了。

2.6.3、成员函数的重载及参数缺省

  • 成员函数也可以重载
  • 成员函数可以带缺省参数
  • 案例如下:
#include <iostream>class Location {private:int x, y;public:void init(int x = 0, int y = 0);// 两个valueX是函数重载关系void valueX(int val) { x = val; }int valueX() { return x; }
};int main() {Location A, B;A.init(5);A.valueX(6);std::cout << A.valueX() ;return 0;
}void Location::init(int x, int y)
{x = x;y = y;
}// OUT
6
  • 注意!!!使用缺省参数需要注意避免有函数重载时的二义性
class Location {private:int x, y;public:void init(int x = 0, int y = 0);两个valueX是函数重载关系(这里存在二义性)void valueX(int val = 0) { x = val; }int valueX() { return x; }
};int main() {Location A;A.valueX();   Error,编译起无法判断调用哪个valueXreturn 0;
}

这篇关于C++面向对象程序设计-北京大学-郭炜【课程笔记(二)】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/717481

相关文章

C++使用printf语句实现进制转换的示例代码

《C++使用printf语句实现进制转换的示例代码》在C语言中,printf函数可以直接实现部分进制转换功能,通过格式说明符(formatspecifier)快速输出不同进制的数值,下面给大家分享C+... 目录一、printf 原生支持的进制转换1. 十进制、八进制、十六进制转换2. 显示进制前缀3. 指

C++中初始化二维数组的几种常见方法

《C++中初始化二维数组的几种常见方法》本文详细介绍了在C++中初始化二维数组的不同方式,包括静态初始化、循环、全部为零、部分初始化、std::array和std::vector,以及std::vec... 目录1. 静态初始化2. 使用循环初始化3. 全部初始化为零4. 部分初始化5. 使用 std::a

C++ vector的常见用法超详细讲解

《C++vector的常见用法超详细讲解》:本文主要介绍C++vector的常见用法,包括C++中vector容器的定义、初始化方法、访问元素、常用函数及其时间复杂度,通过代码介绍的非常详细,... 目录1、vector的定义2、vector常用初始化方法1、使编程用花括号直接赋值2、使用圆括号赋值3、ve

如何高效移除C++关联容器中的元素

《如何高效移除C++关联容器中的元素》关联容器和顺序容器有着很大不同,关联容器中的元素是按照关键字来保存和访问的,而顺序容器中的元素是按它们在容器中的位置来顺序保存和访问的,本文介绍了如何高效移除C+... 目录一、简介二、移除给定位置的元素三、移除与特定键值等价的元素四、移除满足特android定条件的元

利用Python快速搭建Markdown笔记发布系统

《利用Python快速搭建Markdown笔记发布系统》这篇文章主要为大家详细介绍了使用Python生态的成熟工具,在30分钟内搭建一个支持Markdown渲染、分类标签、全文搜索的私有化知识发布系统... 目录引言:为什么要自建知识博客一、技术选型:极简主义开发栈二、系统架构设计三、核心代码实现(分步解析

Python获取C++中返回的char*字段的两种思路

《Python获取C++中返回的char*字段的两种思路》有时候需要获取C++函数中返回来的不定长的char*字符串,本文小编为大家找到了两种解决问题的思路,感兴趣的小伙伴可以跟随小编一起学习一下... 有时候需要获取C++函数中返回来的不定长的char*字符串,目前我找到两种解决问题的思路,具体实现如下:

C++ Sort函数使用场景分析

《C++Sort函数使用场景分析》sort函数是algorithm库下的一个函数,sort函数是不稳定的,即大小相同的元素在排序后相对顺序可能发生改变,如果某些场景需要保持相同元素间的相对顺序,可使... 目录C++ Sort函数详解一、sort函数调用的两种方式二、sort函数使用场景三、sort函数排序

Java调用C++动态库超详细步骤讲解(附源码)

《Java调用C++动态库超详细步骤讲解(附源码)》C语言因其高效和接近硬件的特性,时常会被用在性能要求较高或者需要直接操作硬件的场合,:本文主要介绍Java调用C++动态库的相关资料,文中通过代... 目录一、直接调用C++库第一步:动态库生成(vs2017+qt5.12.10)第二步:Java调用C++

C/C++错误信息处理的常见方法及函数

《C/C++错误信息处理的常见方法及函数》C/C++是两种广泛使用的编程语言,特别是在系统编程、嵌入式开发以及高性能计算领域,:本文主要介绍C/C++错误信息处理的常见方法及函数,文中通过代码介绍... 目录前言1. errno 和 perror()示例:2. strerror()示例:3. perror(

C++变换迭代器使用方法小结

《C++变换迭代器使用方法小结》本文主要介绍了C++变换迭代器使用方法小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录1、源码2、代码解析代码解析:transform_iterator1. transform_iterat