C++学习笔记2

最近上班需要用到C++,之前只系统的学习过C,没有了解过C++的一些特性,业余时间继续去学习一下C++的语法和特性(与C语言相同的部分不再赘述)

字符串、向量和数组

string和vector是两种最重要的标准库类型,前者可支持边长字符串,后者表示可变长集合。

标准库类型string

标准库类型string表示可变长的字符序列,使用string类型必须要包含string头文件(#include<string>)

定义和初始话string

如何初始话类的对象由类本身决定的,一个类可以定义很多种初始话对象的方式,这些方式之间必须有所区别,或者是初始值数量不同,或者是初始值类型不同,例如:

1
2
3
4
string s1; // 默认初始化,s1是空字符串
string s2 = s1; // s2是s1的副本
string s3 = "hello"; // s3是该字符串字面值的副本
string s4(10, 'c'); // s4的内容是10个字符c

string对象上的操作

操作 说明
os << s 将s写道输出流os中,返回os
is >> s 从is中读取字符串赋值给s,字符串以空白分割,返回is
getline(is, s) 从is中读取一行赋给s,返回is
s.empty() s为空返回true,否则返回false
s.size() 返回s中的字符个数
s[n] 返回s中第n个字符的引用
s1+s2 返回s1和s2连接后的结果
s1=s2 用s2的副本代替s1中原来的字符
s1 == s2 如果s1和s2中的字符完全一样,则相等,大小写敏感
<, <=, >, >= 利用字符在字典中的顺序进行比较,且对字母的大小写敏感

标准库类型vector

vector表示对象的集合,其中所有对象的类型都相同。集合中的每个对象都有一个与之对应的索引,索引用于访问对象。

要想使用vector需要包含头文件<vector>,vector是模板而非类型,由vector生成的类型必须包含vector中的元素类型,例如vector[int]

定义和初始化vector对象

初始化vector对象的常用方法:

操作 说明
vector<T> v1 v1是一个空 vector,它潜在的元素是T类型的,执行默认初始化
vector<T> v2 (v1) v2中包含所有v1元素的副本,等价于v2 = v1
vector<T> v3 (n, val) v3包含了n个val
vector<T> v4 (n) 包含了n个重复执行了值初始话的对象
vector<T> v5 {a, b, c…} 每个元素被赋予了初始值,等价于v5 = {a, b, c…}

向vector对象中添加元素

使用v.push_back(var)

C++中无需指定元素数量效率最高,与Java等语言不同

其他vector操作

v.empty():判断是否为空

v.size():判断v中元素的个数

v.push_back(var):向v的尾部添加值为var的元素

v[n]:返回v中第n个位置上的元素引用

C++ 在 C 语言的基础上增加了面向对象编程,C++ 支持面向对象程序设计。类是 C++ 的核心特性,通常被称为用户定义的类型。类用于指定对象的形式,是一种用户自定义的数据类型,它是一种封装了数据和函数的组合。类中的数据称为成员变量,函数称为成员函数。类可以被看作是一种模板,可以用来创建具有相同属性和行为的多个对象。

类的定义

定义一个类需要使用关键字 class,然后指定类的名称,并类的主体是包含在一对花括号中,主体包含类的成员变量和成员函数。定义一个类,本质上是定义一个数据类型的蓝图,它定义了类的对象包括了什么,以及可以在这个对象上执行哪些操作。类成员可以被定义为 public、private 或 protected。默认情况下是定义为 private(如果使用struct构造类,默认情况下定义为public)。

1
2
3
4
5
6
class classname
{
Access specifiers: // 访问修饰符 private/pubilc/protected
Data members/variables // 变量
Member functions(){} // 方法
}; // 分号结束一个类

构造函数

类的构造函数是类的一种特殊的成员函数,它会在每次创建类的新对象时执行。

构造函数的名称与类的名称是完全相同的,并且不会返回任何类型,也不会返回 void。构造函数可用于为某些成员变量设置初始值。

析构函数

类的析构函数是类的一种特殊的成员函数,它会在每次删除所创建的对象时执行。

析构函数的名称与类的名称是完全相同的,只是在前面加了个波浪号(~)作为前缀,它不会返回任何值,也不能带有任何参数。析构函数有助于在跳出程序(比如关闭文件、释放内存等)前释放资源。

this指针

在 C++ 中,this 指针是一个特殊的指针,它指向当前对象的实例。

在 C++ 中,每一个对象都能通过 this 指针来访问自己的地址。

this是一个隐藏的指针,可以在类的成员函数中使用,它可以用来指向调用对象。

拷贝构造函数

拷贝构造函数是一种特殊的构造函数,它在创建对象时,是使用同一类中之前创建的对象来初始化新创建的对象。拷贝构造函数通常用于:

  • 通过使用另一个同类型的对象来初始化新创建的对象。
  • 复制对象把它作为参数传递给函数。
  • 复制对象,并从函数返回这个对象。

如果在类中没有定义拷贝构造函数,编译器会自行定义一个。如果类带有指针变量,并有动态内存分配,则它必须有一个拷贝构造函数。拷贝构造函数的最常见形式如下:

1
2
3
classname (const classname &obj) {
// 构造函数的主体
}

友元函数

类的友元函数是定义在类外部,但有权访问类的所有私有(private)成员和保护(protected)成员,友元函数并不是成员函数

友元可以是一个函数,该函数被称为友元函数;友元也可以是一个类,该类被称为友元类,在这种情况下,整个类及其所有成员都是友元。

如果要声明函数为一个类的友元,需要在类定义中该函数原型前使用关键字 friend

1
2
3
4
5
6
7
class ClassOne
{
double width;
public:
friend void printWidth(ClassOne name); // 友元函数
friend class ClassTwo;// 声明类 ClassTwo 的所有成员函数作为类 ClassOne 的友元,需要在类 ClassOne 的定义中放置该声明,ClassTwo中成员函数可访问ClassOne受保护的和私有的成员
};

一般在类定义的开始或结束前的位置集中声名友元

静态成员

我们可以使用 static 关键字来把类成员定义为静态的。当我们声明类的成员为静态时,这意味着无论创建多少个类的对象,静态成员都只有一个副本。

静态成员在类的所有对象中是共享的。如果不存在其他的初始化语句,在创建第一个对象时,所有的静态数据都会被初始化为零。我们不能把静态成员的初始化放置在类的定义中,但是可以在类的外部通过使用范围解析运算符 :: 来重新声明静态变量从而对它进行初始化。

静态成员函数

如果把函数成员声明为静态的,就可以把函数与类的任何特定对象独立开来。静态成员函数即使在类对象不存在的情况下也能被调用,静态函数只要使用类名加范围解析运算符 :: 就可以访问。

静态成员函数只能访问静态成员数据、其他静态成员函数和类外部的其他函数。静态成员函数有一个类范围,他们不能访问类的 this 指针(因为类实例不存在时也能调用静态成员函数)。

指向类的指针

一个指向 C++ 类的指针与指向结构的指针类似,访问指向类的指针的成员,需要使用成员访问运算符 **->**,就像访问指向结构的指针一样。与所有的指针一样,必须在使用指针之前,对指针进行初始化。在 C++ 中,指向类的指针指向一个类的对象,与普通的指针相似,指向类的指针可以用于访问对象的成员变量和成员函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <iostream>

class MyClass {
public:
int data;

void display() {
std::cout << "Data: " << data << std::endl;
}
};

int main() {
// 创建类对象
MyClass obj;
obj.data = 42;
// 声明和初始化指向类的指针
MyClass *ptr = &obj;

// 动态分配内存创建类对象
// MyClass *ptr = new MyClass;
// ptr->data = 42;

// 通过指针访问成员变量
std::cout << "Data via pointer: " << ptr->data << std::endl;

// 通过指针调用成员函数
ptr->display();

return 0;
}

C++学习笔记2
https://chujian521.github.io/blog/2024/04/13/C-学习笔记2/
作者
Encounter
发布于
2024年4月13日
许可协议