在C++中有智能指针这个概念,智能指针区别于普通的指针,智能指针虽然名字里面有指针两个字,但是却不是指针,指针在C里面是一个特殊类型的变量,这类变量的存储空间与机器字长有关,是用来存放地址的。智能指针是一个泛型类,主要包括auto_prt
、unique_ptr
和shared_prt
这三个类。这三个类的应用场景不太一样,但都提供了一个能力–行为类似于指针,能在合适的时机释放内部指针占用的内存。使用智能指针,不再需要手动调用析构函数。
智能指针实现主要借助了以下特性:
- 栈能够自动管理内存,函数的调用与结束都伴随着入栈出栈
- C++提供了运算符重载,指针用到的操作符主要是
->
和*
这三个模版类都在声明在memory
这个头文件里面。
初始化智能指针对象时,推荐使用这种形式unique_ptr<T> ptr = make_unique<T>(...args);
, T是类型,...args
表示调用T的某个构造函数传入的参数。这样的风格可以和JAVA编程风格基本保持一致。智能指针的使用与普通指针类似,每个指针都有不同的类型,每种不同的类型能够访问不同的成员,调用相应的函数,智能指针要实现这个功能,调用泛型类的方法而不产生语法错误,最好的办法就是通过内部保存的原始指针,在别的不提供运算符重载的语言中一般通过消息转发实现,例如Objective-C中的NSProxy, 考虑到指针最常使用的操作符一般是->
、*
、+
、-
以及++
和--
, 加减这类操作符一般在数组中使用的比较多,其他情况下, ->
和*
比较常见, 源代码重载了这些操作符.
其中->
运算符比较特殊,只能由成员函数重载,此外->
返回一个指针或者类的对象。如果返回的是一个指针,会继续调用->
运算符,比如p->m
,如果重载了p对应类(一般情况下类没有->运算符, 只有指针才有)的->
运算符,返回的是一个指针, 那么重载后替换成的方法调用如下(p.operator->())->m
.
注意⚠️,重载类的->运算符, 不要使用指针去调用, 重载的是类的, 不是对应指针类型的.
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
| #ifndef Human_hpp #define Human_hpp
#include <stdio.h> #include <string>
using namespace std;
class Human { private: string name; int age;
public: Human(string name, int age); Human(); ~Human(); string getName(); int getAge(); void setName(string name); void setAge(int age); void resume(); bool operator>(const Human & other) const { printf("%d > %d", age, other.age); return age > other.age; } bool operator==(const Human & other) const; };
#endif
|
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
| #include "Human.hpp"
int Human::getAge() { return this->age; }
string Human::getName() { return this->name; }
void Human::setAge(int age) { this->age = age; }
void Human::setName(string name) { this->name = name; }
void Human::resume() { printf("Name: %s, Age: %d\n", name.c_str(), age); }
Human::Human(string name, int age) { this->name = name; this->age = age; }
Human::Human() { }
Human::~Human() { printf("clean person(%s)\n", name.c_str()); printf("make some clean work!\n"); }
bool Human::operator==(const Human & other) const { return age == other.age && (strcmp(name.c_str(), other.name.c_str()) == 0); }
|
1 2 3 4 5 6
| int main() { Human *human1 = new Human("pinkman", 27); Human *human2 = new Human("white", 47); printf("*human1 > *human2 ? %s\n", *human1 > *human2 ? "YES" : "NO"); return 0; }
|