C++11新特性
1. enable_shared_from_this
(https://blog.csdn.net/caoshangpa/article/details/79392878)
1.1 作用
- std::enable_shared_from_this 能让一个对象(假设其名为 t ,且已被一个 * std::shared_ptr 对象 pt 管理)安全地生成其他额外的 std::shared_ptr 实例(假设名为 pt1, pt2, … ) ,它们与 pt 共享对象 t 的所有权。
- 若一个类 T 继承 std::enable_shared_from_this ,则会为该类 T 提供成员函数: shared_from_this 。 当 T 类型对象 t 被一个为名为 pt 的 std::shared_ptr 类对象管理时,调用 T::shared_from_this 成员函数,将会返回一个新的 std::shared_ptr 对象,它与 pt 共享 t 的所有权。
1.2 相关问题
-
当类A被share_ptr管理,且在类A的成员函数里需要把当前类对象作为参数传给其他函数时,就需要传递一个指向自身的share_ptr。为何不直接传递this指针?
使用智能指针的初衷就是为了方便资源管理,如果在某些地方使用智能指针,某些地方使用原始指针,很容易破坏智能指针的语义,从而产生各种错误。
-
可以直接传递share_ptr么?
不能,因为这样会造成2个非共享的share_ptr指向同一个对象,未增加引用计数导对象被析构两次
使用
#include <memory> //enable_shared_from_this所需头文件
#include <iostream>
struct Good : std::enable_shared_from_this<Good>
{
public:
std::shared_ptr<Good> getptr() {
return shared_from_this();
}
~Good() { std::cout << "Good::~Good() called" << std::endl; }
};
int main()
{
{
std::shared_ptr<Good> gp1(new Good());
std::shared_ptr<Good> gp2 = gp1->getptr();
// 打印gp1和gp2的引用计数
std::cout << "gp1.use_count() = " << gp1.use_count() << std::endl;
std::cout << "gp2.use_count() = " << gp2.use_count() << std::endl;
}
system("pause");
}
一、符号说明
1. size_t
size_t :是一个类型定义,通常将一些无符号的整形定义为size_t,如unsigned int、unsigned
long、unsigned long long。
在C标准中:
void *malloc(size_t n);
void *memcpy(void *s1, void const *s2, size_t n);
size_t strlen(char const *s)
2. #include中emplace_back()和push_back()
相同:都是在vector的后面添加一个元素
不同:push_back() 向容器尾部添加元素时,首先会创建这个元素,然后再将这个元素拷贝或者移动到容器中(如果是拷贝的话,事后会自行销毁先前创建的这个元素);而 emplace_back() 在实现时,则是直接在容器尾部创建这个元素,省去了拷贝或移动元素的过程。
4. unordered_map emplace()方法
emplace() 语法格式如下:
template <class... Args>
pair<iterator, bool> emplace ( Args&&... args );
输入参数:
其中,参数 args 表示可直接向该方法传递创建新键值对所需要的 2 个元素的值,其中第一个元素将作为键值对的键,另一个作为键值对的值。该方法无需我们手动创建键值对。
返回参数:
该方法的返回值为 pair 类型值,其包含一个迭代器和一个 bool 类型值:
当 emplace() 成功添加新键值对时,返回的迭代器指向新添加的键值对,bool 值为 True;
当 emplace() 添加新键值对失败时,说明容器中本就包含一个键相等的键值对,此时返回的迭代器指向的就是容器中键相同的这个键值对,bool 值为 False。
3. |=
这个称为布尔或赋值运算符”或者“位与赋值运算符”;
int a = 5;
int b = 3;
System.out.println(a|=b);
输出7,
5 的二进制 是 0 11,
3 的二进制 是 0 101
按位或 运算
有一个为1 就是1
结果 : 0 111 (2的二次方+加2的一次方+1) 7
4. L、_T、R
https://www.cnblogs.com/goed/archive/2011/11/11/2245702.html
-
L
字符串前面加L表示该字符串是Unicode字符串。 -
_T、TEXT、_TEXT(一致)
_T是一个宏,如果项目使用了Unicode字符集(定义了UNICODE宏),则自动在字符串前面加上L,否则字符串不变。
TCHAR szStr1[] = TEXT(“str1”);
char szStr2[] = “str2”;
WCHAR szStr3[] = L(“str3”);
第一句话在定义了UNICODE时会解释为第三句话,没有定义时就等于第二句话。
但第二句话无论是否定义了UNICODE都是生成一个ANSI字符串,而第三句话总是生成UNICODE字符串。
为了程序的可移植性,建议都用第一种表示方法。但在某些情况下,某个字符必须为ANSI或UNICODE,那就用后两种方法。 -
LR
const std::experimental::filesystem::path symbolsFilename = LR"(d:\fulongtech_git\draing_recognizer\Datas\Symbols.dxf)";L表示双字节,也就是每个字符占用两个字节,就是可能出现中文,R是里面的字符串都不转义,所以可以加括号什么的
二、函数说明
1. CreateMutex函数函数用来实现进程互斥,防止应用程序多开
HANDLE CreateMutex(
LPSECURITY_ATTRIBUTES lpMutexAttributes, // 指向安全属性的指针
BOOL bInitialOwner, // 初始化互斥对象的所有者
LPCTSTR lpName // 指向互斥对象名的指针
);
如果函数成功执行,将返回一个互斥量对象的句柄。如果在CreateMutex()执行前已经存在有相同名字的互斥量,函数将返回这个已经存在互斥量的句柄,并且可以通过GetLastError()得到错误代码ERROR_ALREADY_EXIST。
三、函数对象(仿函数)
https://blog.csdn.net/hik_zxw/article/details/50435854
1. 什么是函数对象
重载函数调用操作符的类,其对象常称为函数对象,即它们是行为类似函数的对象。又称仿函数。
// 定义函数对象的类一般不需要数据成员,也没有定义的构造函数,因此创建和使用函数对象的开销是最小的
class background_task
{
public:
void operator()() const //函数调用操作符是(),此操作符的函数重载是operator()()。
{
do_something();
do_something_else();
}
};
2. 为什么函数对象比函数指针效率高
由于使用函数对象可以在编译时确定调用的函数,比运行时确定效率高些。而且使用函数对象还有机会内联展开,从而避免了函数调用的开销
3. 函数对象的作用
函数对象提供了一种方式,可以将函数作为实参传递给另一个函数。与使用函数指针相比,这种方式既简单又容易。