目录
一、名称空间
二、重载运算符
三、模板/泛型
一、名称空间
- C++中名称空间可以区别同名C风格函数、同名C风格全局变量、同名类。
- 名称空间还可以无限嵌套。
namespace ns1 { ..... namespace ns2 { ..... } }
- 同一个名称空间名字可以多处书写,比如,在demo1.h中namespace ns1{},在另一个demo1.h中也可以写namespace ns1{}, 最终编译器会认为是同一个名称空间。
- 使用有名称空间的函数、变量或类时,要导入名称空间,可以在文件开头使用"using namespace 名称"导入,也可以在使用时使用 "名称::"。
- 若出现以下情况,调用时需在函数前加入对应的名称空间:
二、重载运算符
1、概念
函数可以重载,运算符也可以重载。C++中预定义的运算符的操作对象只能是基本数据类型。但实际上,对于许多用户自定义类型(例如类),也需要类似的运算操作。这时就必须在C++中重新定义这些运算符,赋予已有运算符新的功能,使它能够用于特定类型执行特定的操作。
2、规则
- C++不允许用户自己定义新的运算符,只能对已有的C++运算符进行重载。
- C++允许重载的运算符, 不能重载的运算符只有5个:"."、"->"、"? : "、"sizeof"、"类型转换运算符(static_cast、dynamic_cast 等)"
- 其中“=”和“&”不必用户重载。
- 重载不能改变运算符运算对象(即操作数)的个数。
- 重载不能改变运算符的优先级别。
- 重载不能改变运算符的结合性。
- 重载运算符的函数不能有默认的参数,否则就改变了运算符参数的个数,与前面第"4"点矛盾
- 重载的运算符必须和用户定义的自定义类型的对象一起使用,其参数至少应有一个是类对象(或类对象的引用)。
- 应当使重载运算符的功能类似于该运算符作用于标准类型数据时所实现的功能
- 运算符重载函数可以是 C函数,友元C函数、类的成员函数
3.示例1:类的成员函数
“+”需要两个操作数,其中this已经代表了i1对象。
4 示例2:(友元)普通函数
友元函数是为了能够访问私有成员,如果x与y改为public,也可以不使用友元。
5 示例3:重载[]
#include <iostream>
using namespace std;
class MyArray {
private:
int arr[5];
public:
int& operator[](int index) {
if (index < 0 || index >= 5) {
// 处理错误情况,例如抛出异常
throw std::out_of_range("Index out of range");
}
return arr[index];
}
};
int main() {
MyArray myArray;
myArray[0] = 10; // 对下标为0的元素进行赋值
int value = myArray[0]; // 获取下标为0的元素的值
cout<<value<<endl;
return 0;
}
6 示例4:重载=
#include <iostream>
using namespace std;
#include<string>
class Test {
private:
int x;
int y;
public:
void show();
Test(int, int);
Test & operator = (const Test &);
};
void Test::show() {
cout<<"x="<<x<<"y="<<y<<endl;
}
Test::Test(int x, int y):x(x),y(y) {cout<<x<<":"<<y<<endl;}
Test & Test::operator = (const Test & obj) {
this->x = obj.x;
this->y = obj.y;
return *this;
}
int main()
{
Test t1(1,2);
Test t2(100,200);
t2 = t1;//触发重写的赋值函数
t2.show();
Test t3 = t1;//触发拷贝构造函数
t3.show();
return 0;
}
7 示例5:前++,后++重载
三、模板/泛型
模板是一多态的一种体现,模板的声明与定义不能分开写在不同文件中,一般开发是把模板的声明与实现放在同一个头文件中。或者直接在头文件中定义。
1、函数模板
声明数据类型参数标识符的关键字既可以用class也可以用typename.它们等效.
template <class 形参名,class 形参名,......>
返回类型 函数名(参数列表)
{ 函数体 }
模板类型接收字符串时如果没有明确类型则会默认为const *char 类型。
编译器会对函数进行函数实例化,分编译器自动实例化和显示实例化
2、函数模板特例化
示例说明:
对于模板函数 T Max(T a, T b)的函数体能处理类型char, int等的处理,但是如果a,b接收到的参数为字符串,则就不能正常处理了,所以针对这种情况,就特化(重写)了新的函数
const char * Max(const char *a, const char *b),函数体中采用新的方式专门用于处理string的大小比较。
3、类模板
类模板可以通过template定义1到多个类型,类的声明与函数实现可以不分开写,如果分开写,要写在同一个头文件中。