重载
C++ 中的函数重载可以发生在全局作用域、类的成员函数以及命名空间中。函数重载的条件是函数名称相同,但参数列表必须不同。参数列表的不同可以通过参数的类型、顺序和个数来实现。返回值类型不同不足以实现函数重载,因为函数重载的决策是在编译时进行的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| #include <iostream>
void display(int num) { std::cout << "Integer: " << num << std::endl; }
void display(double num) { std::cout << "Double: " << num << std::endl; }
int main() { display(10); display(3.14); return 0; }
|
还有一个运算符重载
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| #include <iostream>
class Vector2D { public: double x, y;
Vector2D(double x, double y) : x(x), y(y) {}
Vector2D operator+(const Vector2D& other) { return Vector2D(x + other.x, y + other.y); } };
int main() { Vector2D v1(1.0, 2.0); Vector2D v2(3.0, 4.0); Vector2D result = v1 + v2;
std::cout << "Result: (" << result.x << ", " << result.y << ")" << std::endl;
return 0; }
|
这个没看懂
std::string 类
储和访问字符串内容
储和访问字符串内容:std::string 对象可以存储任意长度的字符串。
您可以使用赋值运算符 = 或构造函数将字符串赋值给 std::string 对象,
并使用 [] 运算符 或 成员函数 at() 来访问字符串中的单个字符。
1 2 3 4
| std::string str = "Hello"; char ch = str[0]; char ch2 = str.at(1);
|
获取字符串长度:
使用 length() 或 size() 成员函数可以获取字符串的长度(字符数)。
1 2
| std::string str = "Hello"; int len = str.length();
|
字符串拼接
使用 + 运算符或 append() 成员函数可以将字符串拼接起来。
1 2 3 4 5 6
| std::string str1 = "Hello"; std::string str2 = "World"; std::string result = str1 + " " + str2;
std::string str3 = "Hello"; str3.append(" World");
|
字符串提取
子字符串提取:使用 substr() 成员函数可以从一个字符串中提取出指定位置和长度的子字符串。
1 2 3
| std::string str1 ="hello, World!" std::string substr = str.substr(7.5);
|
字符串比较
使用 ==、!=、<、> 等运算符可以进行字符串的比较操作。
1 2 3 4
| std::string str1 = "Hello"; std::string str2 = "World"; bool equal = (str1 == str2); bool less = (str1 < str2);
|
类和对象
3大特性 封装 继承 多态
封装
语法: class 类名{ 访问权限: 属性/行为};
一个简单的类的案例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| #include <iostream> #define PI 3.14 using namespace std;
class circle { public: int m_r; double calc(){ return 2 * PI * m_r; } };
int main(){ circle cl; cl.m_r = 10; cout << "圆的周长" << cl.calc() << endl; return 0; }
|
类中的属性与行为 统称为成员
属性 -> 成员属性,变量
行为-> 成员函数
访问权限
- public : 公共权限 // 成员在类内能访问 类外能访问
- protected : 保护权限 // 成员 类内能访问 类外不能访问 -> 儿子可以访问父类的内容
- private : 私有权限 //成员 类内能访问 类外不能访问 -> 儿子拿不到
struct和class 区别:
struct -> 默认权限为public:
class -> 默认权限是private:
将成员属性设为私有
好处:
- 可以自己控制读写的权限
- 对于写权限,我们可以检查数据的有效性
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> #include <string> using namespace std;
class person { private : string m_name; int age =18; string love;
public: void set_name(string name){ m_name = name; } string get_name(){ return m_name; }
};
int main() { person p; p.set_name("张三"); cout << p.get_name() << endl; }
|
初始化和清理
构造函数和析构函数
这两个函数是编译器提供 (可写可不写) ——> 空实现
构造函数: 主要作用在于创建对象时赋值,构造函数由编译器自动调用
析构函数: 主要主用在于对象销毁前
系统自动调用清理工作
构造函数语法: 类名(){}
- 没有返回值,也不写void
- 类名于函数名相同
- 构造函数也有参数,因此可以发生重载
- 程序在调用对象时候会自动调用构造,无需手动调用,只会来一次
析构函数语法 ~类名(){}
- 也没有返回值,不写void
- 类名于函数名相同,前面加~
- 析构函数不能有参数,没重载
- 程序销毁对象时自动析构
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
| #include <iostream> #include <string> using namespace std;
class Person { public: int age; Person() { cout << "无参构造函数" << endl; } Person(int a) { cout << "有参构造" << endl; age = a; } Person(const Person &p) { age = p.age; cout << "拷贝构造" << endl; } ~Person() { cout << "析构函数" << endl; } }; void test01() { Person p;
Person p2(10); Person p3(p2); cout << p2.age << " " << p3.age << endl; } void test02() { Person p1; Person p2 = Person(10); Person p3 = Person(p2); cout << p2.age << " " << p3.age << endl; } void test03() { Person p1 = 10; Person p2 = p1; cout << p1.age << " " << p2.age << endl; } int main() {
test03(); }
|
构造函数分类
如上代码块
拷贝构造函数调用时机
- 使用一个已经创建完毕的对象来初始化另外一个新对象‘
- 值传递的方式给函数参数传值
- 以值方式返回局部对象
深拷贝与浅拷贝
- 浅拷贝:简单的赋值操作
- 深拷贝:在堆区重新申请空间,进行拷贝操作
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| #include <iostream> #include <string> using namespace std;
class Person { public: int age; int *M_hight; Person() { cout << "无参构造函数" << endl; } Person(int a, int hight) { cout << "有参构造函数" << endl; M_hight = new int(hight); age = a; } Person(const Person &p){ cout << "拷贝函数" << endl; age = p.age; M_hight = new int(*p.M_hight); } ~Person() { if (M_hight != NULL) { delete M_hight; M_hight = NULL; } cout << "Person的析构函数" << endl; } };
void test01() { Person p1(19, 160); cout << "p1 " << p1.age << " " << *p1.M_hight << endl; Person p2(p1); cout << "p2 " << p2.age << " " << *p2.M_hight << endl; }
int main() { test01(); }
|
初始化列表
作用:c++提供初始化列表语法
语法: 构造函数():属性1(值),属性2(值)… {}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| class Person { public: int M_a; int M_b; int M_c;
Person(int a,int b ,int c):M_a(a),M_b(b),M_c(c){}
}
|
类作物一个成员
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| class Phone{ public: string p_Name; Phone(string p_name){ p_Name =p_name; } }
class Person{ public:
string m_name;
Phone m_phone; Person(string name,string phone ): m_name(name),m_phone(phone){
}
};
|
静态变量
- 所有对象都共享同一个数据
- 编译阶段就分配内存
- 类内声明,类外初始化操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| class Person { public: static int a; };
void test01(){ Person p; cout << p.a; } int main() {
test01();
}
|
必须初始化且不能初始化在与定义一起
1 2 3 4 5 6 7 8
| void test01() { int Person::a = 100; Person p;
cout << Person::a << endl; }
|
静态变量不属于某一个对象 属于类
通过对象进行访问
通过类名进行访问
1 2 3
| cout << Person:: a << endl; Person p; cout <<p.a << endl;
|
静态变量也有权限
静态函数
- 所有对象都共享同一个函数
- 静态函数只能访问静态成员
对象模型 this指针
函数变量分开存储
- 空对象 ——>c++编译器也给空对象分配一个字节空间 ,是为了区分空对象占内存空位置
- 静态变量不属于对象上
- 函数也是不在
this指针
this指向被调用的成员函数所属的对象
目的:
- 解决名称冲突
- 返回对象
最好成员还是用m_name取名比较好
1:
1 2 3 4 5 6 7 8 9
| class Person { public: int age; Person(int age){ this->age = age; Person ::age = age; } };
|
2:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| class Person { public: int age; Person Person_add(Person &p) { this->age += p.age; return *this; } }; void test01() { Person p(10); Person p2(10); cout << p.Person_add(p2).Person_add(p2).Person_add(p2).age; cout << p.age << endl; }
|
空指针调用成员函数
允许空指针访问函数,但是如果函数有调用类中数据会报错 (段错误)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| class Person { public: int age; void show_name() { cout << "z" << endl; } void show_age() { if(this==NULL){ return; } cout << "age= " << age << endl; } }; void test02() { Person *p = NULL; p->show_name(); }
|
const修饰成员函数
常函数:加const
常函数内不可以修改成员属性
成员属性申明时加上关键词mutale后,在常函数中依旧可以修改
常对象:
- 声明对象前加const
- 常对象只能调用常函数
友元
vector
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| #inlcude<vector> using namespace std; std::vector <int> number={1,2,3}; numbers.push_back(4); numbers.pop_back(); int element=number[2]; int b=number.at(2); int size=number.size(); bool isempty=number.empty(); for(int i=0;i<number.size();i++ ){ } for (int num : numbers) { std::cout << num << " "; } std::cout << std::endl; numbers.clear(); std::vector<int>::iterator it=numbers.begin(); auto its==numbers.begin(); int fristelement=*its;
|
其他
将字符串 数字 相互转换
将数字转化为字符串
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| int num =42; std::string str= std::to_string(num);
int num = 42; std::ostringstream oss; oss << num; std::string str = oss.str();
double num = 3.14159; std::ostringstream oss; oss << std::fixed << std::setprecision(4) << num; std::string str = oss.str();
int num = 42; char buffer[32]; std::sprintf(buffer, "%d", num); std::string str(buffer);
|
将字符串转化为数字
1 2 3 4 5 6 7 8 9 10 11
| std::string str = "42"; int num = std::stoi(str);
str = "3.14159"; float fnum = std::stof(str);
const char* cstr = "42"; int num = std::atoi(cstr);
cstr = "3.14159"; double dnum = std::atof(cstr);
|