阅读很多C++代码会发现有impl的影子随处可见,为什么要在一个类里面定义一个impl的class内部类呢?
我想主要是为了隐藏内部实现吧。
class Layer {
public:
Layer(const Layer& ) = delete;
Layer& operator=(const Layer&) = delete;
virtual ~Layer();
class Impl;
Immutable<Impl> baseImpl;
}
class Layer::Impl {
public:
Impl(std::string layerID, std::string sourceID);
virtual ~Impl() = default;
}
Immutable
*从’ Mutable
- as ‘ std::shared_ptr
‘,但有更好的意图指示。
* - 通常不应该在线程之间共享状态,因为很难验证
没有读/写数据竞争。’ Immutable ‘保证没有写操作
因此,实例可以在线程之间自由传输和共享。
派生类不仅有自己的方法和属性,同时它还包括从父类继承来的方法和属性。
当我们从派生类向基类转换时,不管用传统的c语言还是c++转换方式都可以百分百转换成功。
但是可怕是向下转换类型,也就是我们从基类向派生类转换,当我们采用传统的C语言和c++转换时,
就会出现意想不到的情况,因为转换后派生类自己的方法和属性丢失了,
一旦我们去调用派生类的方法和属性那就糟糕了,这就是对类继承关系和内存分配理解不清晰导致的。
好在c++增加了static_cast和dynamic_cast运用于继承关系类间的强制转化
static_cast< new_type >(expression)
dynamic_cast< new_type >(expression)
备注:new_type为目标数据类型,expression为原始数据类型变量或者表达式。
static_cast相当于传统的C语言里的强制转换,该运算符把expression转换为new_type类型,用来强迫隐式转换如non-const对象转为const对象,编译时检查,用于非多态的转换,可以转换指针及其他,但没有运行时类型检查来保证转换的安全性。它主要有如下几种用法:
①用于类层次结构中基类(父类)和派生类(子类)之间指针或引用的转换。
进行上行转换(把派生类的指针或引用转换成基类表示)是安全的;
进行下行转换(把基类指针或引用转换成派生类表示)时,由于没有动态类型检查,所以是不安全的。
②用于基本数据类型之间的转换,如把int转换成char,把int转换成enum。
③把空指针转换成目标类型的空指针。
④把任何类型的表达式转换成void类型。
注意:static_cast不能转换掉expression的const、volatile、或者__unaligned属性
char a = ‘a’;
int b = static_cast
double *c = new double;
void *d = static_cast<void*>(c);//正确,将double指针转换成void指针
int e = 10;
const int f = static_cast
const int g = 20;
int *h = static_cast<int*>(&g);//编译错误,static_cast不能转换掉g的const属性
class Base
{};
class Derived : public Base
{}
Base* pB = new Base();
if(Derived* pD = static_cast<Derived*>(pB))
{}//下行转换是不安全的(坚决抵制这种方法)
Derived* pD = new Derived();
if(Base* pB = static_cast<Base*>(pD))
{}//上行转换是安全的
dynamic_cast:
转换方式:
dynamic_cast< type* >(e)
type必须是一个类类型且必须是一个有效的指针
dynamic_cast< type& >(e)
type必须是一个类类型且必须是一个左值
dynamic_cast< type&& >(e)
type必须是一个类类型且必须是一个右值处链接及本声明。
e的类型必须符合以下三个条件中的任何一个:
1、e的类型是目标类型type的公有派生类
2、e的类型是目标type的共有基类
3、e的类型就是目标type的类型。
dynamic_cast主要用于类层次间的上行转换和下行转换,还可以用于类之间的交叉转换
尽量少使用转型操作,尤其是dynamic_cast,耗时较高,会导致性能的下降,尽量使用其他方法替代。
std::move函数可以以非常简单的方式将左值引用转换为右值引用
std::move是将对象的状态或者所有权从一个对象转移到另一个对象,只是转移,没有内存的搬迁或者内存拷贝所以可以提高利用效率,改善性能.。
std::make_unique
make_unique 同 unique_ptr 、auto_ptr 等一样,都是 smart pointer,可以取代new 并且无需 delete pointer,有助于代码管理。
make_unique 创建并返回 unique_ptr 至指定类型的对象,这一点从其构造函数能看出来。make_unique相较于unique_ptr 则更加安全。
std::bind
bind的思想实际上是一种延迟计算的思想,将可调用对象保存起来,然后在需要的时候再调用。而且这种绑定是非常灵活的,不论是普通函数、函数对象、还是成员函数都可以绑定,而且其参数可以支持占位符,比如你可以这样绑定一个二元函数auto f = bind(&func, _1, _2);,调用的时候通过f(1,2)实现调用。
std::unique_ptr
std::shared_ptr
emplace
三个成员emplace_front、emplace 和 emplace_back。这些操作构造而不是拷贝元素到容器中,这些操作分别对应push_front、insert 和push_back,允许我们将元素放在容器头部、一个指定的位置和容器尾部。
当调用insert时,是将对象传递给insert,对象被拷贝到容器中,而当我们使用emplace时,是将参数传递给构造函,emplace使用这些参数在容器管理的内存空间中直接构造元素。
emplace_back能通过参数构造对象,不需要拷贝或者移动内存,相比push_back能更好地避免内存的拷贝与移动,使容器插入元素的性能得到进一步提升。