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

2024-02-15 15:52

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

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

  • 1、引用的概念
    • 1.1、引用应用的简单示例
    • 1.2、常引用
  • 2、"const"关键字的用法(常量指针/指针常量)
  • 3、动态内存分配
  • 4、内联函数
  • 5、函数重载
    • 5.1、什么是函数重载
    • 5.2、函数的缺省参数

1、引用的概念

下面的写法定义了一个引用,并将其初始化为引用某哥变量。
类型名 & 引用名 = 某变量名;
某个变量的引用,等价于这个变量,相当于该变量的一个别名

// 模板
int = 4;
int & r = n;  // r引用了n,r的类型是int & //案例
int n = 7;
int & r = n;
r = 4;
cout << r; //输出4
cout << n; //输出4

注意事项:
1、定义引用时一定要将其初始化成引用某个变量
2、初始化后,它就一直引用该变量。
3、引用只能引用变量不能引用常量
案例如下:

double a = 4, b = 5;
double & r1 = a;
double & r2 = r1;   // r2也引用a
r2 = 10;
cout << a << endl;  // 输出 10
r1 = b;             // r1 并没有引用b
cout << a << endl;  // 输出 5

1.1、引用应用的简单示例

题目:C语言中,如何编写交换两个整形变量值的函数?

  • 值传递
// 值传递
void swap(int a, int b)
{int tmp;tmp = a; a = b; b = tmp;
}
int n1, n2;
swap(n1, n2);  // n1, n2的值不会被交换
  • 指针传递
// 指针传递
void swap(int * a, int * b)
{int tmp;tmp = *a; *a = *b; *b = tmp;
}
int n1, n2;
swap(& n1, &n2);  // n1, n2的值会被交换
  • 引用传递
// 引用传递
void swap(int & a, int & b)
{int tmp;tmp = a; a = b; b = tmp;
}
int n1, n2;
swap(n1, n2);  // n1, n2的值会被交换
  • 引用案例
int n = 4;
int & SetValue() {return n;}
int main()
{SetValue() = 40;cout << n;return 0;
}  
// 输出:40

1.2、常引用

定义引用时,前面加const关键字,即为常引用

int n;
const int & r = n;
r 的类型是 const int &

常引用的特点

不能通过常引用去修改其引用的内容:
int n = 100;
const int & r = n;
r = 200; // 编译报错
n = 300; // 编译没问题

const type & 和 type & 是不同类型!!!

1、type &类型的引用或type类型的变量可以用来初始化const type & 类型的引用
2、const type 类型的常变量和const type & 类型的引用则不能用来初始化type 类型的引用,除非进行强制类型转化

2、"const"关键字的用法(常量指针/指针常量)

1)定义常量

const int MAX_VAL = 23;
const double Pi = 3.14;
// 常量字符串类型的指针
const char * SCHOOL_NAME = "Peking University";

2)常量指针

注意事项1:不可通过常量指针修改其指向的内容,但常量指针的指向可以发生变化

int n,m;
const int * p = &n;
* p = 5;   // 编译出错
n = 4;     // 编译OK
p = &m;    // 编译OK,常量指针的指向可以发生变化

注意事项2:不能把常量指针赋值给非常量指针,反过来可以(如下案例)

const int * p1;   // 常量指针
int * p2;         // 指针
p1 = p2;          // 编译OK
p2 = p1;          // 编译error
p2 = (int *)p1;   // 编译OK,强制类型转换

注意事项3:函数参数为常量指针时,可避免函数内部不小心改变参数指针所指地方的内容。

void MyPrintf(const char * p)
{// 函数strcpy第一个参数是char型,p是const char型strcpy(p, "this");  //编译errorprintf("%s", p);    //OK
}

3、动态内存分配

用new运算符实现动态内存分配

  • 第一种用法,分配一个变量

P = new T;
T是任意类型名,P是类型为T * 的指针。
动态分配出一片大小为sizeof(T)字节的内存空间,并且将该内存空间的其实地址复制给P。比如:

int * pn;
pn = new int;
* pn = 5;
  • 第二种用法,分配一个数组

P = new T[N];
T:任意类型名;P:类型为T * 的指针;N:要分配的数组元素的个数,可以是整形表达式。
动态分配出一片大小为N * sizeof(T);字节的内存空间,并将该内存空间的起始地址赋值给P;

int * pn;
int i = 5;
pn = new int[i * 20];  // i✖️20个元素
pn[0] = 20;
pn[100] = 30;		// 编译OK。运行时error数组越界
  • new 运算符的返回值类型;
new T;
new T[n];

这两个表达式返回值的类型都是T *

int * p = new int;
  • 用delete运算符释放动态分配的内存

1、用“new” 动态分配的内存空间,一定要“delete”运算符进行释放
delete 指针; // 该指针必须执行new出来的空间

int * p = new int;
* p = 5;
delete p;
delete p;   // error,一片空间不能被delete多次

2、用“delete”释放动态分配的数组,要加“[]”
delete [] 指针; // 该指针必须执行new出来的空间

int * p = new int[20];
p[0] = 1;
delete [] p;

4、内联函数

  • 函数调用是有时间开销的。如果函数本身就只包含几条语句,执行非常快,由于函数被反复执行很多次,相比之下调用函数所产生的这个开销就会显得比较大。
  • 为了减少函数调用的开销,引入了内联函数机制。编译起处理内联函数的调用语句时,是将整个函数的代码插入到调用语句处,而不会产生调用函数的语句。
  • 使用内联函数的缺点也是非常明显的,编译后的程序会存在多份相同的函数拷贝,如果被声明为内联函数的函数体非常大,那么编译后的程序体积也将会变得很大,所以再次强调,一般只将那些短小的、频繁调用的函数声明为内联函数。

在函数定义前面加“inline”关键字,即可定义内联函数

inline int Max(int a, int b){if(a > b) return a;return b;
}

如在在主函数中调用内联函数k = Max(n1, n2);,编译器会将其变成如下形式:

if (n1, n2)tmp = n1;
else tmp = n2;k = tmp;

5、函数重载

5.1、什么是函数重载

函数重载一个或多个函数,名字相同,然而参数个数参数类型不相同,这叫函数的重载。
以下三个函数是重载关系:

int Max(double f1, double f2) { };
int Max(int n1, int n2) { };
int Max(int n1, int n2, int n3) {};

作用

  • 函数重载使得函数命名变得简单。
  • 编译器根据调用语句中的实参的个数和类型判断应该调用哪个函数。
(1)    int Max(double f1, double f2) { };
(2)    int Max(int n1, int n2) { };
(3)    int Max(int n1, int n2, int n3) {};
Max(3.4, 2.5);    // 调用(1)
Max(2,4);         // 调用(2)
Max(1, 2, 3);     // 调用(3)
Max(3, 2.4);      // error,二义性

5.2、函数的缺省参数

C++中,定义函数的时候可以让最右边的连续若干个参数有缺省值,那么调用函数的时候,若相应位置不写参数,参数就是缺省值。

void func(int x1, int x2 = 2, int 3 = 3) {}func(10);       // 等效于func(10, 2, 3)
func(10, 8);    // 等效于func(10, 8, 3)
func(10, , 8);  // error,只能最右边的连续若干个参数缺省
  • 函数参数可缺省的目的在于提高程序的可扩充性
  • 即如果某个写好的函数要添加新的参数,而原先那些调用该函数的语句,未必需要使用新增的参数,那么为了避免对原先那些函数调用语句的修改,就可以使用缺省函数。

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



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

相关文章

深入解析C++ 中std::map内存管理

《深入解析C++中std::map内存管理》文章详解C++std::map内存管理,指出clear()仅删除元素可能不释放底层内存,建议用swap()与空map交换以彻底释放,针对指针类型需手动de... 目录1️、基本清空std::map2️、使用 swap 彻底释放内存3️、map 中存储指针类型的对象

C++ STL-string类底层实现过程

《C++STL-string类底层实现过程》本文实现了一个简易的string类,涵盖动态数组存储、深拷贝机制、迭代器支持、容量调整、字符串修改、运算符重载等功能,模拟标准string核心特性,重点强... 目录实现框架一、默认成员函数1.默认构造函数2.构造函数3.拷贝构造函数(重点)4.赋值运算符重载函数

C++ vector越界问题的完整解决方案

《C++vector越界问题的完整解决方案》在C++开发中,std::vector作为最常用的动态数组容器,其便捷性与性能优势使其成为处理可变长度数据的首选,然而,数组越界访问始终是威胁程序稳定性的... 目录引言一、vector越界的底层原理与危害1.1 越界访问的本质原因1.2 越界访问的实际危害二、基

Python学习笔记之getattr和hasattr用法示例详解

《Python学习笔记之getattr和hasattr用法示例详解》在Python中,hasattr()、getattr()和setattr()是一组内置函数,用于对对象的属性进行操作和查询,这篇文章... 目录1.getattr用法详解1.1 基本作用1.2 示例1.3 原理2.hasattr用法详解2.

c++日志库log4cplus快速入门小结

《c++日志库log4cplus快速入门小结》文章浏览阅读1.1w次,点赞9次,收藏44次。本文介绍Log4cplus,一种适用于C++的线程安全日志记录API,提供灵活的日志管理和配置控制。文章涵盖... 目录简介日志等级配置文件使用关于初始化使用示例总结参考资料简介log4j 用于Java,log4c

C++归并排序代码实现示例代码

《C++归并排序代码实现示例代码》归并排序将待排序数组分成两个子数组,分别对这两个子数组进行排序,然后将排序好的子数组合并,得到排序后的数组,:本文主要介绍C++归并排序代码实现的相关资料,需要的... 目录1 算法核心思想2 代码实现3 算法时间复杂度1 算法核心思想归并排序是一种高效的排序方式,需要用

C++11范围for初始化列表auto decltype详解

《C++11范围for初始化列表autodecltype详解》C++11引入auto类型推导、decltype类型推断、统一列表初始化、范围for循环及智能指针,提升代码简洁性、类型安全与资源管理效... 目录C++11新特性1. 自动类型推导auto1.1 基本语法2. decltype3. 列表初始化3

C++11右值引用与Lambda表达式的使用

《C++11右值引用与Lambda表达式的使用》C++11引入右值引用,实现移动语义提升性能,支持资源转移与完美转发;同时引入Lambda表达式,简化匿名函数定义,通过捕获列表和参数列表灵活处理变量... 目录C++11新特性右值引用和移动语义左值 / 右值常见的左值和右值移动语义移动构造函数移动复制运算符

C++中detach的作用、使用场景及注意事项

《C++中detach的作用、使用场景及注意事项》关于C++中的detach,它主要涉及多线程编程中的线程管理,理解detach的作用、使用场景以及注意事项,对于写出高效、安全的多线程程序至关重要,下... 目录一、什么是join()?它的作用是什么?类比一下:二、join()的作用总结三、join()怎么

C++中全局变量和局部变量的区别

《C++中全局变量和局部变量的区别》本文主要介绍了C++中全局变量和局部变量的区别,全局变量和局部变量在作用域和生命周期上有显著的区别,下面就来介绍一下,感兴趣的可以了解一下... 目录一、全局变量定义生命周期存储位置代码示例输出二、局部变量定义生命周期存储位置代码示例输出三、全局变量和局部变量的区别作用域