函数重载 :在同一作用域的名字相同的参数列表(参数个数 或 类型 或 类型顺序)不同的函数,当不重载的俩名字相同的函数同时调用会调用歧义
当你使用 C++ 编写程序时,你可以通过函数重载来创建多个具有相同名称但不同参数的函数。这样做有助于提高代码的可读性和灵活性。下面是一个简单易懂的示例:
#include <iostream>
// 定义两个重载的函数
void print(int x) {
std::cout << "Printing integer: " << x << std::endl;
}
void print(double x) {
std::cout << "Printing double: " << x << std::endl;
}
int main() {
int a = 5;
double b = 3.14;
// 调用不同版本的函数
print(a); // 调用 void print(int x)
print(b); // 调用 void print(double x)
return 0;
}
在这个例子中,我们有两个名为 print
的函数,一个接受整数参数,另一个接受双精度浮点数参数。当你调用 print
函数时,编译器会根据传递的参数类型自动确定应该调用哪个版本的函数。这样,即使函数名相同,但由于参数类型不同,所以不会产生调用歧义。
引用:& int& b = a; (b是a的别名)同一个地址
引用的定义必须初始化、一个变量可以有多个引用、引用一旦引用一个实体,再不能引用其它实体。 权限不可以放大,可以平移和缩小 。指针和引用才设计权限的放大和缩小。
传引用的效率比传值的效率高 类型转换会先生成临时变量,表达式也会产生临时变量,临时变量有常性,引用时引用的是临时变量所以要加const修饰
引用在底层和指针是一样的,语法层引用不开空间,指针开空间,但底层都开空间。
引用自增就是实体加一,指针自增是加一个类型大小,引用比指针更安全
下面是一个简单的 C++ 示例,演示了引用的一些特性:
#include <iostream>
// 传引用的函数,交换两个整数的值
void swap(int& x, int& y) {
int temp = x;
x = y;
y = temp;
}
int main() {
int a = 5;
int& b = a; // b 是 a 的别名
// 输出 a 和 b 的值
std::cout << "a: " << a << std::endl;
std::cout << "b: " << b << std::endl;
// 修改 b 的值,同时也修改了 a 的值
b = 10;
// 输出修改后的 a 和 b 的值
std::cout << "After modifying b:" << std::endl;
std::cout << "a: " << a << std::endl;
std::cout << "b: " << b << std::endl;
// 交换 a 和 b 的值
swap(a, b);
// 输出交换后的 a 和 b 的值
std::cout << "After swapping:" << std::endl;
std::cout << "a: " << a << std::endl;
std::cout << "b: " << b << std::endl;
return 0;
}
内联函数:inline 适用与使用多的函数规模小的函数
但内联函数的函数比较大的时候不会展开 ,inline对编译器只是一个建议
内联函数不建议声明和定义分类
#include <iostream>
// 内联函数定义在头文件中
inline int add(int a, int b) {
return a + b;
}
int main() {
int num1 = 5;
int num2 = 10;
// 调用内联函数
int sum = add(num1, num2);
std::cout << "Sum: " << sum << std::endl;
return 0;
}
auto可以替代比较长的类型的定义,简化代码 auto不能作为函数的参数,不能用来声明数组
范围for: c++11 :自动取数组array中,赋值给e,自动++,自动判断结束 不能在函数中,因为传过去的是地址,范围for只能对数组使用
for(auto e : array)
{
cout << e << “ “;
}
cout << endl;
#include <iostream>
#include <vector>
int main() {
// 定义一个整数数组
int array[] = {1, 2, 3, 4, 5};
// 使用范围-based for 循环遍历数组
std::cout << "Array elements:";
for (auto e : array) {
std::cout << " " << e;
}
std::cout << std::endl;
return 0;
}
NULL的本质是0,是宏替换,nullptr是(void)*0,以后c++用nullptr更合适。
typeid自动看对象的类型
类和对象 c++升级了结构体:
1个类 实例化N个对象 1、类里面可以定义函数(成员函数) 2、struct名称就可以代表类型
变短了,不用传参数了
访问限定符:共有:public 可以在类外面访问, 私有:protected private 在类外不能直接被访问,struct默认公有,class默认私有。一般成员变量私有,成员函数公有。体现封装特性 访问权限作用域从改访问限定符出现的位置开始直到下一个访问限定符出现为止
面向对象的三大特性:封装、继承、多态
同一类的对象的成员变量是不一样的,成员函数是一样的,使用同一的函数地址
空类的大小是1,这一个字节不存储有效有效数据,标识对象被定义出来
隐含的this指针:
- 实参和形参的位置不能显示写,编译器自己加
- 但是在类里面可以用
类的6个默认成员函数:空类是编译器自动生成的成员函数
- 构造函数 :构造函数是特殊的成员函数,需要注意的是,构造函数虽然名称叫构造,但是构造函数的主要任务并不是开空间创建对象,而是初始化对象。
其特征如下:
1. 函数名与类名相同。
2. 无返回值。
3. 对象实例化时编译器自动调用对应的构造函数。
4. 构造函数可以重载
当使用无参的构造函数不能带括号—与函数声明分不开,一个类想写几个构造函数都可以·····
一般情况,建议每个类都写一个全缺省的构造(好用)
我们没写,有构造函数,编译器自动生成的构造函数,对于内置类型成员变量,没有规定要不要做处理!(有些编译器会处理); 对于自定义类型成员变量才会调用他的无参构造
#include <iostream>
#include <string>
// 定义一个简单的类
class Person {
private:
std::string name;
int age;
public:
// 构造函数,无参构造函数
Person() {
name = "Unknown";
age = 0;
}
// 带参数的构造函数
Person(std::string n, int a) {
name = n;
age = a;
}
// 打印个人信息
void displayInfo() {
std::cout << "Name: " << name << ", Age: " << age << std::endl;
}
};
int main() {
// 使用无参构造函数创建对象
Person person1;
std::cout << "Person 1: ";
person1.displayInfo();
// 使用带参数的构造函数创建对象
Person person2("John", 30);
std::cout << "Person 2: ";
person2.displayInfo();
return 0;
}
在这个示例中,我们定义了一个简单的类 Person
,它有两个私有成员变量 name
和 age
,以及两个构造函数:一个是无参构造函数,另一个是带参数的构造函数。无参构造函数用于创建对象时初始化成员变量为默认值,而带参数的构造函数用于根据传入的参数初始化对象的成员变量。在 main
函数中,我们分别使用这两种构造函数创建了两个 Person
对象,并调用了 displayInfo
函数来打印对象的信息。
- 析构函数: 析构函数是特殊的成员函数,其特征如下:
1. 析构函数名是在类名前加上字符 ~。
2. 无参数无返回值类型。
3. 一个类只能有一个析构函数。若未显式定义,系统会自动生成默认的析构函数。注意:析构函数不能重载
4. 对象生命周期结束时,C++编译系统系统自动调用析构函数
在这个示例中,我们定义了一个简单的类#include <iostream> #include <string> // 定义一个简单的类 class Person { private: std::string name; public: // 构造函数 Person(std::string n) : name(n) { std::cout << "Constructor called for " << name << std::endl; } // 析构函数 ~Person() { std::cout << "Destructor called for " << name << std::endl; } }; int main() { // 创建对象 Person person1("Alice"); Person person2("Bob"); // 对象生命周期结束,自动调用析构函数 return 0; }
Person
,它有一个私有成员变量name
,并且有一个带参数的构造函数和一个析构函数。在main
函数中,我们创建了两个Person
对象person1
和person2
,当它们超出作用域时,即程序执行到main
函数的末尾时,它们的生命周期结束,系统会自动调用它们的析构函数,输出相应的信息。