类型转换
C++中有4个类型转换符
- static_cast : 常用于基本数据类型的转换、非const转成const,不是同一继承体系的,无法转换
- dynamic_cast :一般用于多态类型的转换,有运行时安全检测
- reinterpret_cast:属于比较底层的强制转换,没有任何类型检查和格式转换,仅仅是简单的二进制数据拷贝
- const_cast : 去除const
const Person *p1 = new Person();
Person *p2 = const_cast<Person *>(p1);
Person *p1 = new Person();
Person *p2 = new Student();
Student *stu1 = dynamic_cast<Student *>(p1); // NULL
Student *stu2 = dynamic_cast<Student *>(p2); // 安全
Car *c1 = (Car *) p1;
Car *c2 = dynamic_cast<Car *>(p2); //NULL
//报错 不是同一继承体系
Car *c2 = static_cast<Car *>(p1);
auto 类型推到
int a = 10;
auto func = [a]() mutable {
a++;
cout << "lambda = " << a << endl;
};
decltype 类似于iOS的typeof 获取类型
int a = 10;
decltype(a) b = 20;
匿名函数 Lambda表达式
完整结构:
[capture list] (params list) mutable exception-> return type { function body }
简略:
[capture list] (params list) -> return type {function body}
[capture list] (params list) {function body}
[capture list] {function body}
改变外部变量的值 mutable
int a = 10;
auto func = [a] () mutable {
a++;
cout << "lambda = " << a << endl;
};
智能指针 shared_ptr 于 weak_ptr
智能指针的简单实现,其实就类似于iOS的引用计数.
- 一个shared_ptr会对一个对象产生强引用(strong reference)
- 每个对象都有个与之对应的强引用计数,记录着当前对象被多少个shared_ptr强引用着(所以也存在着循环引用的问题,这个时候需要搭配weak_ptr使用)
- 当有一个shared_ptr销毁时(比如作用域结束),对象的强引用计数就会-1
- 当一个对象的强引用计数为0时(没有任何shared_ptr指向对象时),对象就会自动销毁(析构)
template <typename T>
class SmartPointer {
private:
T *m_obj;
public:
SmartPointer(T *obj) :m_obj(obj) {}
~SmartPointer() {
if (m_obj == nullptr) return;
delete m_obj;
}
T *operator->() {
return m_obj;
}
};
重复析构,会crash
Person* p = new Person();
{
shared_ptr<Person> p1(p);
}
{
shared_ptr<Person> p2(p);
}
循环引用
类似于下面那样,只需要将Person里面的share_ptr改为weak_ptr
class Person{
public:
shared_ptr<Car> m_car = nullptr;
};
class Car {
public:
shared_ptr<Person> m_person = nullptr;
};
int main() {
shared_ptr<Person> person(new Person());
shared_ptr<Car> car(new Car());
person->m_car = car;
car->m_person = person;
return 0;
}
unique_ptr
- unique_ptr也会对一个对象产生强引用,它可以确保同一时间只有1个指针指向对象
- 当unique_ptr销毁时(作用域结束时),其指向的对象也就自动销毁了
- 可以使用std::move函数转移unique_ptr的所有权
//ptr强引用这Person对象
unique_ptr<Person> ptr(new Person());
//转移所有权
unique_ptr<Person> ptr2 = std::move(ptr);