2111 字
11 分钟
C++基础知识1208
C++中指针和引用的区别
- 引用的特性:创建必须初始化,不能初始化为空,不能改变引用的指向,没有常引用
- 指针可以初始化为空,引用不可以
- 指针可以指向另一个内存地址,引用不可以改变指向
拷贝构造
-
拷贝构造函数的概念:
- 将一个对象的值复制给另一个对象
- 参数使用万能引用在C++98中提出,既可以接收右值也可以接收左值
- 将一个对象的值复制给另一个对象
-
浅拷贝:如果对象有指针成员变量,只会复制指针的地址,而不会复制指针指向的内容
- 这意味着,原始对象和拷贝对象将共享相同的内存资源,一个对象修改或释放了这块内存,都会影响到其他对象
- 写法:
class Person {public:char* name;// 浅拷贝Person(const Person& other) {name = other.name; // 只复制指针地址}}; -
深拷贝:会为对象的指针成员变量分配新的地址空间,并将指针指向的内容也一并复制
- 这样,原始对象原始对象和拷贝对象将有独立的地址空间,彼此之间的修改互不影响
- 写法:
class Person {public:char* name;// 深拷贝Person(const Person& other) {name = new char[strlen(other.name) + 1]; // 先开辟相同大小的空间strcpy(name, other.name); // 复制指针所指向的内容}}; -
完整代码:
#include <iostream>#include <cstring>
class Person {public: char* name;
// 构造函数 Person(const char* n) { name = new char[strlen(n) + 1]; strcpy(name, n); }
// 拷贝构造函数(浅拷贝) Person(const Person& other) { name = other.name; // 浅拷贝,只复制指针地址 }
// 深拷贝构造函数 Person(const Person& other) { name = new char[strlen(other.name) + 1]; strcpy(name, other.name); // 深拷贝,复制指针所指向的内容 }
// 析构函数 ~Person() { delete[] name; }};
int main() { Person p1("Alice"); Person p2 = p1; // 浅拷贝,p2.name 和 p1.name 指向相同的内存
p1.name[0] = 'B'; // 修改 p1 的 name std::cout << "p2.name: " << p2.name << std::endl; // 输出 "Blice",p2.name 也被修改了
Person p3(p1); // 深拷贝,p3.name 和 p1.name 拥有独立的内存空间
p1.name[0] = 'C'; // 修改 p1 的 name std::cout << "p3.name: " << p3.name << std::endl; // 输出 "Blice",p3.name 不受影响
return 0;}
移动构造
-
概念:C++11引入的特性,用于将一个对象的资源==高效的==转移给另一个对象(如动态分配的内存、文件句柄等),而不进行不必要的数据拷贝
- 作用:可以提高性能
- 使用场景:
- 处理大型对象
- 频繁传递临时对象
- 使用场景:
- 如何接收被移动的对象:使用右值引用,并将其资源转移到新对象中,同时原对象会被置为==有效==但==未指定状态==,避免资源==重复==释放
- 移动构造通常使用
std::move
函数将对象转换为右值引用
- 作用:可以提高性能
-
写法:
class MyString {public: char* data; int length;
// 移动构造函数 MyString(MyString&& other) noexcept : data(other.data), length(other.length) { other.data = nullptr; // 将原始对象的资源置为空指针 other.length = 0; }};
- noexcept:
- 写法:写在函数末尾
void fun() noexcept {}
- 作用:表示该函数不会抛出异常
- 写法:写在函数末尾
静态变量
-
分为:静态全局变量和静态局部变量
-
算上静态成员变量,三者的区别:
-
作用域:
- 静态全局变量:
- 整个源文件
- 在定义它的源文件中,源文件的任何位置都能访问
- 注意:在头文件中创建全局变量,要使用静态全局变量
- 整个源文件
- 静态局部变量:
- 定义它的函数内
- 函数外无法直接访问
- 定义它的函数内
- 静态成员变量:
- 类内
- 可以通过类名或对象访问,但是不能通过对象访问非静态成员变量
- 类内
- 静态全局变量:
-
存储位置:
- 静态全局变量:
- 根据是否被显式初始化放在不同位置:
- 被显式初始化:data段
- 没被显式初始化:bss段
- 没被显示初始化的会被赋值成0或空指针
- 根据是否被显式初始化放在不同位置:
- 静态局部变量:
- 存储在data段
- 静态成员变量:
- 存储在静态数据区
- 静态全局变量:
-
生命周期:
- 静态全局变量:
- 与程序生命周期相同
- 静态局部变量:
- 从定义位置到程序结束
- 静态成员变量:
- 与程序生命周期相同
- 静态全局变量:
-
-
静态成员变量的特性:
- 初始化:必须初始化,并且要在类外初始化
- 属于:属于类不属于对象,存在静态数据区(全局区)
- 使用sizeof计算的时候不会计算静态成员变量的大小
- 继承:静态成员变量不会被继承,父类和子类共享静态成员变量,可以通过==类名==或==对象名==访问公有的静态成员变量
初始化参数列表
- 特性:
- 是初始化不是赋值
- 所以,变量的初始化顺序与成员变量的生命顺序一样,与参数列表中的顺序无关
- 常量和引用要在初始化参数列表中初始化
- 显示调用父类构造,因为父类没有无参构造,创建子类对象必须创建父类对象,所以需要在子类的初始化参数列表中显示调用父类的构造函数
- 构造函数:用于给成员变量赋值,初始化对象
- 显示调用父类构造,因为父类没有无参构造,创建子类对象必须创建父类对象,所以需要在子类的初始化参数列表中显示调用父类的构造函数
- 是初始化不是赋值
C++初始化顺序,主函数前面执行什么?
- 按全局变量的创建顺序初始化全局变量
C和C++的区别
-
重载:
- C++支持,C不支持
- 重载的特性:
- 函数名相同
- 参数不同(类型,个数,顺序)
- 与返回值无关
- 一般发生在同一个==类==或==作用域==中
- 为什么C不支持:与这两门语言的编译特性有关
- 重载的特性:
- C++支持,C不支持
-
引用:
- C++支持,C不支持
-
多态:
- C++支持:
- 父类指针指向子类对象,实现动态绑定
- C不支持:
- 多态是面向对象的特性,C是面向过程的语言
- C++支持:
-
malloc和new:
-
C++:
- 使用new运算符动态分配内存,并自动调用对象的构造函数进行初始化
- 使用delete运算符释放内存,并自动调用析构函数
-
C:
- 使用malloc函数分配内存,不会自动调用构造函数初始化
- 使用free函数释放内存,不会自动调用析构函数
-
-
内存管理:
- C++:
- 自动管理内存,避免内存泄漏或者资源的错误使用
- 创建对象或销毁对象时会自动的调用构造函数和析构函数
- 自动管理内存,避免内存泄漏或者资源的错误使用
- C:
- 手动管理内存:
- 没有自动构造和析构的功能
- 手动管理内存:
- C++:
extern
- 用途:用于声明外部变量或函数
- 注意:对于全局变量,即使不使用 extern 关键字进行声明,如果直接在头文件中定义,也会被默认视为 extern 类型,因此在头文件中定义全局变量时通常不需要加上 extern 关键字
c++类和结构体有什么区别
- 默认访问权限和默认继承权限不同
- 类默认私有,结构体默认公有
野指针与悬挂指针
- 野指针:
- 创建没有初始化
- 访问时:由于指向的内存区域是未知的或已经被释放的,会导致==程序崩溃==、==数据损坏==等不可预知的后果
- 悬挂指针:
- 释放没有置空
- 访问时:由于指针指向的内存区域已经被释放,会导致==程序崩溃==、==数据损坏==等不可预知的后果
new和malloc的区别
- malloc返回值需要强转,new不需要
- malloc申请失败返回空指针(NULL),new抛出异常
- new是运算符,malloc是库函数
- new不需要传递具体的字节数,malloc需要传入字节个数
- new先调用malloc,再调用构造函数
malloc出错会发生什么
- 内存泄漏:如果 malloc 返回空指针,但是程序没有进行处理或检查,可能导致内存泄漏
数组指针和指针数组的区别
- 指针数组:存放指针的数组
int* a[3];
- 数组指针:数组的指针,a1+=1,移动的内存是 3 * 4 = 12
int (*a1)[3];
- *和a1被括起来表示的是,a1是指针变量,指向的是大小为12个字节的int类型的数组
指针函数和函数指针
- 指针函数:函数的返回值是指针类型
- 函数指针:指向函数的指针
C++基础知识1208
https://fuwari.cbba.top/posts/c基础知识1208/