终极免费Switch模拟器:Ryujinx完全指南,10分钟开启PC游戏新纪元
2026/5/26 23:53:32
open→read/write→close,开发者需关注每一步的实现细节。打开/读写/关闭方法,开发者只需调用对象的方法,无需关注内部实现。MyLcd l;// 创建 LCD 对象(自动完成初始化)l.DrawRectangle(200,100);// 调用对象方法画矩形l.DrawCircle(300,700,300);// 调用对象方法画圆l.LcdClose();// 调用对象方法关闭设备对象实例化时自动调用,用于初始化对象的成员变量,解决“对象使用前必须初始化”的问题(如 LCD 设备需先打开才能使用)。
void都不能写),函数名与类名完全一致。#include<iostream>#include<cstring>usingnamespacestd;classPerson{private:intage;charname[32];public:// 1. 无参构造(默认构造)Person(){age=0;name[0]='\0';// 字符串初始化(避免垃圾值)}// 2. 单参构造(int 类型)Person(inta){age=a;name[0]='\0';}// 3. 单参构造(字符串类型)Person(constchar*n){age=0;strncpy(name,n,sizeof(name)-1);// 安全拷贝,避免数组越界name[sizeof(name)-1]='\0';}// 4. 多参构造Person(inta,constchar*n){age=a;strncpy(name,n,sizeof(name)-1);name[sizeof(name)-1]='\0';}// 5. 带默认参数的构造函数Person(inta=18,constchar*n="unknown"){age=a;strncpy(name,n,sizeof(name)-1);name[sizeof(name)-1]='\0';}};{}初始化(C++11 新标准,避免歧义):Person p1;// 调用无参构造Person p2{18};// 调用单参构造(int)Person p3{"penglei"};// 调用单参构造(字符串)Person p4{20,"ZhangSan"};// 调用多参构造Person p5{22,"LiSi"};// 调用带默认参数的构造(覆盖默认值)Person p();会被编译器识别为“函数声明”,而非对象实例化,需避免。public(允许外部实例化对象)。private(如单例模式,限制对象创建数量)。classPeople{private:intage;string name;// 后续改用 string 类,更安全便捷string addr;public:// 无参构造People():age(0),name("unknown"),addr("unknown"){}// 全参构造People(inta,conststring&n,conststring&ad):age(a),name(n),addr(ad){}// 打印信息voidShowInfo(){cout<<"Age: "<<age<<", Name: "<<name<<", Addr: "<<addr<<endl;}};// 调用示例intmain(){People p1;p1.ShowInfo();// 输出:Age: 0, Name: unknown, Addr: unknownPeople p2{25,"WangWu","Beijing"};p2.ShowInfo();// 输出:Age: 25, Name: WangWu, Addr: Beijingreturn0;}对象生命周期结束时自动调用,用于清理资源(如关闭文件、释放动态内存、解绑设备等),避免资源泄漏。
~,与类名一致。classMyLcd{private:intfd=-1;// 文件描述符unsignedint*plcd=nullptr;// 内存映射指针public:// 构造函数:打开 LCD 设备MyLcd(){fd=open("/dev/fb0",O_RDWR);if(fd==-1){cerr<<"LCD open failed!"<<endl;return;}// 内存映射等初始化操作...cout<<"LCD initialized!"<<endl;}// 析构函数:关闭设备、释放资源~MyLcd(){if(plcd!=nullptr){munmap(plcd,800*480*4);// 释放内存映射plcd=nullptr;}if(fd!=-1){close(fd);// 关闭文件fd=-1;}cout<<"LCD resource released!"<<endl;}};intmain(){MyLcd l1;// 构造 l1MyLcd l2;// 构造 l2// 生命周期结束时,先析构 l2,再析构 l1return0;}// 输出:// LCD initialized!// LCD initialized!// LCD resource released!// LCD resource released!return(可能导致初始化/清理不完整)。解决“构造函数体内无法初始化某些成员”的问题,例如:
const修饰,必须初始化且不可修改)。类名(参数列表):成员变量1(初始值1),成员变量2(初始值2),...{// 构造函数体(可选,用于后续逻辑处理)}classStudent{private:constintid;// 常量成员(必须初始化)int&scoreRef;// 引用成员(必须初始化)string name;public:// 初始化列表初始化常量、引用、普通成员Student(intstudentId,int&score,conststring&studentName):id(studentId),scoreRef(score),name(studentName){// 构造函数体可省略(无额外逻辑时)}voidShow(){cout<<"ID: "<<id<<", Name: "<<name<<", Score: "<<scoreRef<<endl;}};// 调用示例intmain(){intmathScore=95;Student stu{1001,mathScore,"ZhaoLiu"};stu.Show();// 输出:ID: 1001, Name: ZhaoLiu, Score: 95mathScore=98;// 修改被引用的变量stu.Show();// 输出:ID: 1001, Name: ZhaoLiu, Score: 98(引用同步变化)return0;}char name[32]),初始化列表无法直接赋值,需在构造函数体内用strcpy等函数处理。引用是变量的“别名”,与原变量指向同一块内存空间,操作引用等价于操作原变量。用于替代指针,解决指针的野指针、空指针等安全问题。
类型& 引用名 = 原变量;(必须在定义时初始化)。inta=1024;int&b=a;// b 是 a 的别名,与 a 共享内存b=2048;// 修改 b 等价于修改 acout<<a<<endl;// 输出:2048cout<<&a<<" "<<&b<<endl;// 地址相同// 引用版 swap 函数(无需解引用,简洁安全)voidswap(int&a,int&b){inttemp=a;a=b;b=temp;}// 调用示例intmain(){intx=10,y=20;swap(x,y);// 直接传变量,无需传地址cout<<x<<" "<<y<<endl;// 输出:20 10return0;}// 正确示例:返回静态变量的引用int&getStaticValue(){staticintval=0;// 静态变量,生命周期与程序一致val++;returnval;}// 正确示例:返回传入的引用参数string&appendStr(string&s,conststring&suffix){s+=suffix;returns;}// 调用示例intmain(){cout<<getStaticValue()<<endl;// 输出:1cout<<getStaticValue()<<endl;// 输出:2string str="Hello";appendStr(str," World");cout<<str<<endl;// 输出:Hello Worldreturn0;}| 特性 | 引用 | 指针 |
|---|---|---|
| 初始化 | 定义时必须初始化 | 可定义时不初始化(野指针风险) |
| 空值 | 无空引用(更安全) | 有空指针(nullptr) |
| 重新绑定 | 一旦绑定,无法修改 | 可随时改变指向的变量 |
| 内存开销 | 不占用额外内存(仅别名) | 占用内存(存储变量地址) |
| 多级使用 | 无多级引用(int&& a是右值引用,非多级) | 有多级指针(int** p) |
| 安全性 | 高(无野指针、无需解引用) | 低(需手动管理,避免野指针) |
| 传参/返回值 | 简洁直观,无需解引用 | 需用*解引用,&取地址 |
替代 C 语言的char*字符串,解决数组越界、手动管理内存等问题,提供丰富的字符串操作接口,安全且便捷。
#include<string>// 注意:不是 <string.h>(C 语言头文件)usingnamespacestd;// 或 using std::string;// 1. 无参构造(空字符串)string s1;// 2. 用字符构造(n 个 ch)strings2(5,'a');// s2 = "aaaaa"// 3. 用 C 风格字符串构造strings3("hello");// s3 = "hello"// 4. 用 C 风格字符串的前 n 个字符构造strings4("hello world",5);// s4 = "hello"// 5. 用初始化列表构造string s5{'h','e','l','l','o'};// s5 = "hello"// 6. 拷贝构造(用其他 string 对象构造)strings6(s3);// s6 = "hello"string s7=s3;// 等价于 s6string s;s='A';// 赋值单个字符s="hello";// 赋值 C 风格字符串string s2="world";s=s2;// 赋值 string 对象s+="!";// 追加字符串(operator+= 重载)string s1="Hello";string s2="World";string s3=s1+" "+s2;// s3 = "Hello World"支持==、!=、<、>、<=、>=,按字典序比较:
string a="apple";string b="banana";cout<<(a<b)<<endl;// 输出:1(true,"apple" 字典序小于 "banana")cout<<(a=="apple")<<endl;// 输出:1(true)string s="abcdefg";// 1. operator[]:无越界检查(效率高)charc1=s[2];// c1 = 'c's[3]='X';// s = "abcefg" → 修正:s 变为 "abcXefg"// 2. at():有越界检查,越界抛异常(安全)charc2=s.at(4);// c2 = 'e'try{s.at(10);// 越界,抛 std::out_of_range 异常}catch(constexception&e){cerr<<e.what()<<endl;}// 3. front() / back():获取首/尾字符charfirst=s.front();// 'a'charlast=s.back();// 'g'// 4. data() / c_str():返回 C 风格字符串(const char*)constchar*cStr=s.c_str();// 用于兼容 C 语言接口(如 open、printf)printf("%s\n",cStr);// 输出:abcXefgstring s="hello";cout<<s.size()<<endl;// 输出:5(字符个数)cout<<s.length()<<endl;// 输出:5(与 size() 等价)cout<<s.empty()<<endl;// 输出:0(false,非空)cout<<s.max_size()<<endl;// 输出:字符串最大可容纳的字符数(系统相关)s.clear();// 清空字符串(size() 变为 0)cout<<s.empty()<<endl;// 输出:1(true)string s="hello";// 1. 追加s.push_back('!');// 尾部追加字符 → "hello!"s+=" world";// 尾部追加字符串 → "hello! world"// 2. 插入s.insert(5,",");// 在索引 5 处插入字符 → "hello,! world"// 3. 删除s.erase(5,1);// 从索引 5 开始,删除 1 个字符 → "hello! world"// 4. 查找size_t pos=s.find("world");// 查找子串,返回起始索引(6)if(pos!=string::npos){// 找到返回索引,未找到返回 string::nposcout<<"Found at: "<<pos<<endl;}// 5. 替换s.replace(6,5,"C++");// 从索引 6 开始,替换 5 个字符 → "hello! C++"// 6. 截取子串string sub=s.substr(6,3);// 从索引 6 开始,截取 3 个字符 → "C++"当需要调用 C 语言函数(如open、fopen)时,用c_str()转换为const char*:
string path="/mnt/share/test.txt";// 调用 C 语言 open 函数intfd=open(path.c_str(),O_RDWR);if(fd==-1){perror("open failed");}