news 2026/5/8 15:45:04

C++笔记

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
C++笔记

注释:单行//;多行/**/。

右键源文件点击编译生成.obj;右键项目点击生成输出.exe文件

全局变量会默认初始化,局部变量不会初始化。

条件?执行1:执行2

调试输入输出

//输出 std::cout << 输出内容1 << 输出内容2 << ...; std::cerr << "错误信息:" << 变量 << ...; std::clog << "执行到第" << n << "步"; //输入 std::cin >> 变量1 >> 变量2 >> ...;

数组扩展vector模板类(还包括array:固定长度),可使数组长度变为动态的,需加头文件#include<vector>

使用:vector<数据类型(如int)> 变量名;初始化:vector<int> a(5,100),五个变量都为100

获取长度.size;添加元素.push_back;

Enum:枚举数据类型

自定义类型别名

typedef int arrayT[5];//arrayT是一个自定义的类型别名,表示长度为5的int数组

命名空间

#include <iostream> using namespace std; // 第一个命名空间 namespace first_space{ void func(){ cout << "Inside first_space" << endl; } } // 第二个命名空间 namespace second_space{ void func(){ cout << "Inside second_space" << endl; } } int main () { // 调用第一个命名空间中的函数 first_space::func(); // 调用第二个命名空间中的函数 second_space::func(); return 0; }

数组

静态数组
double balance[5] = {1000.0, 2.0, 3.4, 7.0, 50.0};
动态数组
std::vector<int> vec; // 初始大小为0(空动态数组) vec.push_back(10); // 添加元素10,大小变为1

指针

指针:带有*,赋值时使用取地址符号&获取变量的地址给到指针变量,要获取指针指向的变量可以使用*指针名来解指针

定义空指针:int* p=nullptr/NULL/0

指针变量指向常量:const int* p=&pi(指向的数据必须是常量,但指针本事为变量可以指向不同的常量)

常量指针:int* const p=&i(指向的数据需是变量,但指针本事是常量,指定后不可更改,但解引用后可以修改)

for(int num:arr) { cout<<num<<endl; }
指针数组、数组指针

指针数组:一个数组,它的所有元素都是相同类型的指针;

int* pa[4];

数组指针:一个指针,指向一个数组的指针;

int(* pb)[4];
智能指针
  1. std::unique_ptr<T>:独占资源所有权的指针。
  2. std::shared_ptr<T>:共享资源所有权的指针。
  3. std::weak_ptr<T>:共享资源的观察者,需要和 std::shared_ptr 一起使用,不影响资源的生命周期。
引用(起别名)的用法,可减少数据拷贝
int a = 10; int& ref = a;

引用不占内存,可减少数据拷贝,函数形参使用引用的话能够实现对实参的修改

void Sadd(int & p) { p++; } int main() { int x = 1; Sadd(x);}

结构体的引用取内部值本写为(*curr).next;可简化为curr->next

使用数组引用作为形参:

void printArray(const int(& arr)[5]) { for (int num:arr) cout<<num<<endl; }

static静态对象:离开作用域依然保留, 创建时不做初始化会默认为0值

//显示自身被调用多少次的函数 int callCount() { static int count = O;//只会被调用一次,且变量一直存在 ++count; cout<<"我被调用了”<<count<<”次!"<< endl; return count; }

数据结构:数组、结构、类、链表、栈、队列、映射、集合

动态数组:vector容器
#include <vector>//首先需要引入头文件 //创建 std::vector<int> myVector; std::vector<int> myVector(5, 10); // 创建一个包含 5 个整数的 vector,每个值都为 10 std::vector<int> vec2 = {1, 2, 3, 4}; // 初始化一个包含元素的 vector //添加元素 myVector.push_back(7); // 将整数 7 添加到 vector 的末尾 //删除元素 myVector.erase(myVector.begin() + 2); // 删除第三个元素 //迭代访问 for (auto it = myVector.begin(); it != myVector.end(); ++it) { std::cout << *it << " "; } //或者 for (int element : myVector) { std::cout << element << " "; } //并且可以使用嵌套,定义二维容器 vector<vector<int>> outer;

函数

不拷贝的函数使用

const string & longStr(const string& str1,const string& str2) { return str1.size()> str2.size() ? str1:str2; }

函数返回类型:指向数组的指针

int fun(int x);//普通int返回值函数声明 int(*fun(int x))[5];//返回值类型为数组指针的函数声明 //方法2 typedef int arrayT[5];//arrayT是一个自定义的类型别名,表示长度为5的int数组 arrayT*fun2(int x);//同上 //方法3,尾置返回类型 auto fun3(int x)->int(*)[5]

内敛函数:inline关键词,运行效率会更高,会将使用到的函数在当前位置展开,而不会跳转节省函数调用开销(一般在函数频繁调用且函数内部代码很少的情况下使用内联)

函数指针:

int printBig(int a,int b) { return a>b?a:b; } int main() { int(*fp)(int,int)=nullptr;//定义方法:函数返回类型(*指针名称)(参数类型) fp = printBig;//赋值:可直接用函数名赋值或加取地址符 }

95-函数指针定义和用法

函数指针作为形参:还可作为函数返回值

面向对象

class myClassname//定义一个类,myClassname为类名 { public: int a=0; private: //数据类型分为静态和动态,类中的静态变量只能在类外赋值,静态变量所有对象共用同一个, //静态成员函数只能访问静态变量且不需要对象就可以调用, static int b; } myClassname abc;//创建一个该类型的对象,abc为对象名 //调用类的静态变量或函数可直接访问,访问时使用:: if(myClass::b==0)std::cout << "true"<< " "; //调用类的非静态函数或变量只能通过创建对象访问,访问时使用. if(abc.a==0)std::cout << "true"<< " ";

struct或class,struct定义的类默认是公有的,class默认是私有的,其他没区别

访问权限:public、private(只有自身可以访问)、protected(子类中可以访问)

类函数的声明和实现

构造函数:1,在创建对象的时候,自动调用
2,构造函数名和类名一样,没有返回类型声明

析构函数:1,在对象的生命周期结束,自动调用
2,析构函数和类名一样,在前面加一个~

class Stu { Stu()//构造函数会在创建对象时自动调用,可以做一些初始化 { cout<<init<<endl; } ~Stu()//析构函数 { cout<<destory<<endl; } } { Stu stu1,stu2;//先构造的后析构,如同堆栈 }

拷贝构造函数

移动构造函数

继承
class Dog { private: int m_age; public: int age(); void setAge(int age);//声明 }; int Dog::age()//实现 { return m_age; }

多继承

class Animal { public: string name; } class myDog:public Animal,public Dog { string color; }
重载

C++ 允许在同一作用域中的某个函数运算符指定多个定义,分别称为函数重载运算符重载

多态
// 基类 Animal class Animal { public: // 虚函数 sound,为不同的动物发声提供接口 virtual void sound() const { cout << "Animal makes a sound" << endl; } }; // 派生类 Dog,继承自 Animal class Dog : public Animal { public: // 重写 sound 方法 void sound() const override { cout << "Dog barks" << endl; } }; // 测试多态 int main() { Animal* animalPtr; // 基类指针 // 创建 Dog 对象,并指向 Animal 指针 animalPtr = new Dog(); animalPtr->sound(); // 调用 Dog 的 sound 方法 delete animalPtr; // 释放内存,调用 Dog 和 Animal 的析构函数 return 0; }

虚函数:有关键字virtual修饰的函数为虚函数,只有虚函数可以在子类中重写,其中const表示函数不可修改成员变量

纯虚函数

  • 纯虚函数是没有实现的虚函数,在基类中用 = 0 来声明。
  • 纯虚函数表示基类定义了一个接口,但具体实现由派生类负责。
  • 纯虚函数使得基类变为抽象类(abstract class),无法实例化。
class Shape { public: virtual int area() = 0; // 纯虚函数,强制子类实现此方法 };

虚析构函数

使用说明:

  • 基类是抽象类 / 接口类(如IFlyable),且会被其他类继承;
  • 代码中存在 “基类指针 / 引用指向派生类对象”,且会通过基类指针delete对象;
  • 基类有其他虚函数(如纯虚函数Fly()),说明这个类设计为 “多态使用”,必须配套虚析构。

反例:如果去掉virtual ~IFlyable() {},运行下面的代码会出现内存泄漏(派生类的析构函数不会被调用)

#include <iostream> using namespace std; // 无虚析构的纯虚类(模拟接口) class IFlyable { public: virtual void Fly() = 0; // 去掉虚析构:vretual ~IFlyable() {} }; // 派生类 class Bird : public IFlyable { public: Bird() { cout << "Bird 构造" << endl; } ~Bird() { cout << "Bird 析构" << endl; } // 派生类析构 void Fly() override { cout << "Bird 飞" << endl; } }; int main() { // 基类指针指向派生类对象(接口的典型用法) IFlyable* fly = new Bird(); fly->Fly(); // 删除基类指针 delete fly; return 0; }
Bird 构造 Bird 飞

模板

作用:建立一个通用函数,其函数返回值类型和形参类型可以不具体制定,用一个虚拟的类型来代表。

语法:

template<typename/class T>//声明一个模板,告诉编译器T是一个通用数据类型 void mySwap(T &a,T &b) { T temp =a; a=b; b=temp;} //使用时可以让其自动推导数据类型,也可显式指定类型 mySwap(a,b); mySwamp<int>(a,b);

模板函数和普通函数调用规则

1.如果函数模板和普通函数都可以实现,优先调用普通函数
2.可以通过空模板参数列表来强制调用函数模板
3.函数模板也可以发生重载
4.如果函数模板可以产生更好的匹配,优先调用函数模板

模板具体化

template<class T> bool func(T a,T b)//如果传入自定义数据类型无法直接判断是否相等则会报错 { if(a==b) return true; else return false;} //利用具体化实现特定数据类型的使用,具体化优先调用 template<>bool func(struct a,struct b) { if.....}
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/8 15:44:55

抖音视频批量下载终极指南:3分钟快速掌握高效下载技巧

抖音视频批量下载终极指南&#xff1a;3分钟快速掌握高效下载技巧 【免费下载链接】douyin-downloader A practical Douyin downloader for both single-item and profile batch downloads, with progress display, retries, SQLite deduplication, and browser fallback suppo…

作者头像 李华
网站建设 2026/4/10 6:16:48

基于File-Based App开发MVP项目交

Issue 概述 先来看看提交这个 Issue 的作者是为什么想到这个点子的&#xff0c;以及他初步的核心设计概念。?? 本 PR 实现了 Apache Gravitino 与 SeaTunnel 的集成&#xff0c;将其作为非关系型连接器的外部元数据服务。通过 Gravitino 的 REST API 自动获取表结构和元数据&…

作者头像 李华
网站建设 2026/4/10 6:16:36

ReplaceItems.jsx:用参数化思维重构设计对象替换工作流

ReplaceItems.jsx&#xff1a;用参数化思维重构设计对象替换工作流 【免费下载链接】illustrator-scripts Adobe Illustrator scripts 项目地址: https://gitcode.com/gh_mirrors/il/illustrator-scripts 在数字设计领域&#xff0c;对象替换是一项既基础又关键的工作&a…

作者头像 李华
网站建设 2026/4/10 6:11:24

cmake之旅(8)

cmake之旅&#xff08;8&#xff09;cmake之旅&#xff08;8&#xff09;&#xff1a;Modern CMake 与 target 思维1 传统 CMake 的问题2 Modern CMake 的核心思想3 深入理解 PUBLIC、PRIVATE、INTERFACE3.1 PRIVATE —— 自己用&#xff0c;不传播3.2 PUBLIC —— 自己用&…

作者头像 李华
网站建设 2026/4/10 6:10:16

零基础入门YOLOv10:用官方镜像3步搞定工业缺陷识别

零基础入门YOLOv10&#xff1a;用官方镜像3步搞定工业缺陷识别 1. YOLOv10镜像快速上手 1.1 为什么选择YOLOv10官版镜像 YOLOv10官版镜像是一个开箱即用的深度学习环境&#xff0c;特别适合想要快速上手目标检测的新手开发者。这个镜像已经预装了所有必要的软件和依赖项&…

作者头像 李华