C++基础
iwehdio的博客园:https://www.cnblogs.com/iwehdio/
1、C++基础
- C++相对C语言增加了,面向对象的通用算法。
- C标准库的C++移植:大部分C标准库的头文件 x.h 在C++中为 cx 。
- 多行注释:
/* */
,单行注释://
。 - 标准输入输出头文件:
#include<iostream>
。 cout
是标准输出流变量(对象),代表控制台窗口。<<
是输出运算符。cin
和>>
与之对应。endl
换行。- 名字空间:解决命名冲突问题。如名字空间 std 下的 cout 表示为:
std::cout
。也可以在程序开头声明整个名字空间:using namespace std;
。 - 文件操作:
#include<fstream>
。- 打开并写入文件:
ofstream oF("文件路径");
。 - 写入内容:
oF<<写入内容;
。 - 关闭文件:
oF.close();
。 - 打开并读取文件:
ifstream iF("文件路径");
。 - 读取内容:
iF>>接收内容的变量;
。
- 打开并写入文件:
2、C++函数
-
引用变量:其他变量的别名。
- 如:
int a = 1; int &r = a;
。 - 定义引用变量时就必须指明引用的是哪一个变量,且一旦定义就不能再引用其他变量。
- 引用变量和被引用的变量类型必须匹配,对引用变量的操作就是对它引用的变量的操作。
- 如:
-
引用形参:
-
C函数是值参数,对形参的改变不会改变实参。
-
如:
void swap(int x, int y){ int t = x; x = y; y = t; } int main(){ int a = 3, b = 4; swap(a,b); }
实际上,a 和 b 的值还是原来的3、4,没有发生交换。
-
C语言中为了改变实参,需要传递指针。
-
C++中使用引用实参表达,即函数定义为
void swap(int &x, int &y)
,其他相对上述程序不变。 -
同样的符号作为定义变量和运算符的含义不同。作为定义变量的
*
表示定义指针类型的变量,作为运算符的*
表示获取该地址存储的内容。作为定义变量的&
表示定义引用类型的变量,作为运算符的&
表示取该变量的地址值。
-
-
函数的默认形参:
- 函数的形参可以有默认值:
void func(char ch, int n = 1);
。 - 默认形参必须在非默认形参的右边:
int add(int y, int x = 1, int z = 3);
。
- 函数的形参可以有默认值:
-
函数重载:
-
C++允许作用域内有同名的函数,只要他们的形参不同。
-
函数名和形参列表构造了函数的签名。
-
不能根据返回类型区分。
-
-
函数模板:
-
将数据类型泛型化,编写通用算法。
-
用
template
关键字增加一个模板头,将数据类型变成类模板参数。 -
使用时传入实际所需的模板参数进行实例化。
-
如:
template<typename T> T add(T x, T y){ return x + y; } //传递实际的模板参数 int cout << add<int>(5, 3);
-
3、string和vector
-
string :是一个用户定义类型,表示的是字符串。
- 定义:
string s = "hello";
。 - 用成员运算符 . 访问 string 类的成员:
.size()
:字符串大小。.substr(f, e)
:从原字符串中获取索引从 f 到 e 的子串。+
:字符串拼接。s[x]
:获取或赋值索引为 x 的值。.find(子串)
:获取子串在原字符串中的位置。.insert(index, 子串)
:在 索引为 index 的位置插入子串。
- 定义:
-
vector :向量,类似于数组,但可以动态生长。
-
头文件:
#include<vector>
。 -
是一个类模板,实例化产生一个类。如
vector<int> v = {1,2,3,4};
。 -
v.push_bach(element);
:在最后添加一个元素。 -
v.size();
:向量大小。 -
v.pop_back();
:弹出最后一个元素。 -
v.resize(size);
:重新定义大小,留下前 size 个元素。
-
4、指针和动态内存分配
-
指针:指针就是地址,变量的指针就是变量的地址。可以用取地址运算符
&
获得一个变量的地址。 -
指针变量:存储指针(地址)的变量。
T *p
表示 p 是存储 T类型变量的地址 的变量。 -
通过取内容运算符
*
可以得到一个指针指向的变量。*p
就是p指向的变量。-
如:
int a = 3; int *p = &a; /* 此时,p == &a *p == a */ int *q = p; // 此时,*p == *q == a
-
-
申请 n 个 int 大小的内存:
int *p = new int[n];
。 -
释放内存:
delete p;
,否则会出现内存泄漏。如果是数组则delete[] p;
。
5、 类和对象
程序是由不同种类的许多对象相互协作完成。有哪些对象?对象有什么类型?对象直接有什么关系?
-
C++中如何定义一个类: struct 或 class 关键字。( struct 中的成员默认 public ,class 中的成员默认 private )
class student { public: string name; public: double score; public: void print(){ cout<<name<<score; } }; student stu; //实例化对象 stu.name = "A"; //赋值 stu.score = 78;
-
类类型的指针变量:T 是一个类类型,则 T * 就是 T 指针类型。T * 变量可以指向一个类对象。
student stu; student *p = &stu; //两种访问成员的方法: (*p).name = "B"; //取内容运算符* p->score = "C"; //间接访问运算符->
-
指向动态分布的对象。
student *p = new student; p->name = "D"; delete p;
-
类体外也可以定义成员函数,但要声明作用域
void student::print(){}
。 -
this 指针:指向调用成员方法的对象。
-
一般成员变量为设置为 private ,通过 get 和 set 函数获取和修改。
-
构造函数:创建对象时自动调用的,函数名和类名相同且没有返回类型的函数。默认构造函数为
student(){}
。如果自定义了构造函数,则不再自动生成默认构造函数。
6、重载
-
运算符重载:
- cout << 实际上的完整函数名是:
operator<<()
。
ostream& operator<<(ostream &o, student s){ cout << s.name << s.score; return o; } cout << stu;
- cin >> 同理,除了为了修改student 的成员变量,输入应用引用。
istream& operator>>(istream &in, student &s){ cin >> s.name >> s.score; return in; } cin >> stu;
- cout << 实际上的完整函数名是:
-
friend 关键字:外部函数无法访问类的私有成员,可以用 friend 关键字声明该函数是类的友元函数。
friend ostream& operator<<(ostream &o, student s);
-
下标运算符必须在类中重载,即成员方法:
class point { public: double x, y; //用下标获取数据 double operator[](int n) const { //常函数,不会对成员变量进行修改 if(n == 0){ return x; } else { return y; } } //用下标更改数据需要返回引用,通过 const 关键字重载 double& operator[](int n){ if(n == 0){ return x; } else { return y; } } }
-
拷贝构造函数:用一个对象赋值给另一个对象。
-
没有定义会自动生成默认拷贝构造函数,执行硬拷贝。
class String { char *data; int n; public: String(const String &s){ data = s.data; n = s.n; } }
-
硬拷贝会导致两个对象指向同一块内存,改变其中一个,另一个也会随之改变。
-
对于引用数据类型的成员变量,需要重写拷贝构造函数:
String(const String &s){ data = new char[s.n + 1]; n = s.n; for(int i=0;i<n;i++) data[i] = s.data[i]; data[n] = ' '; }
-
-
析构函数:在函数执行完后释放内存。
-
不带参数也没有返回类型。
-
默认析构函数:
~String(){}
。 -
有引用数据类型的,用 delete 释放内存。
~String(){ if(data) delete[] data; }
-