C++11深入学习知识点整理(一)

学习C++11过程中逐渐整理的知识点和引用链接,特粘出来供大家参考下。(知识点的整理是无规则的,还有些不是C++11的,也整合在一起了。毕竟能新学到几个知识点,也够本了。。)


[博客引用]

<https://www.cnblogs.com/5iedu/category/1007185.html<深入应用C++11>>

<https://www.cnblogs.com/5iedu/category/1503320.html<Modern C++ 11/14>>

[pod类型]

<https://blog.csdn.net/dashuniuniu/article/details/50042341<C++11中的POD和Trivial>>

[表达式的值类型]

<https://www.jianshu.com/p/4538483a1d8a<C++11 中的左值、右值和将亡值>>

<https://blog.csdn.net/zwvista/article/details/5459774<C++0x新概念:glvalue, xvalue, prvalue(泛左值,x值,纯右值)>>

<https://www.jianshu.com/p/52bc35b2e680<C++值类别>>

表达式根据其值的类型可分为以下三类:

lvalue:左值,即传统意义上的左值。

xvalue(expiring value):x值,指通过“右值引用”产生的对象。这里x可以理解为即将消失(expiring),也可理解为中间(横跨左值和右值)。

prvalue(pure rvalue):纯右值,即传统意义上的右值。

两种复合类型:

glvalue(general lvalue):泛左值,由左值和x值构成。泛左值具有动态的类型和对象属性。

rvalue:右值,由x值和纯右值构成。右值具有潜在的可移动性。

 

 

[引用(左值和右值)和移动语义和完美转发]

<https://www.jianshu.com/p/61ea80fcf943<C++11中的右值引用和移动语义>>

<https://www.jianshu.com/p/d19fc8447eaa<[c++11]我理解的右值引用、移动语义和完美转发>>

<https://www.cnblogs.com/yi-mu-xi/p/9896461.html<c++11中 std::ref() 和 引用>>

<https://www.jianshu.com/p/277675675593<std::ref()和&>>

$左值引用和右值引用和universal references(通用引用)

- 右值引用就是对一个右值进行引用的类型,因为右值不具名,因此只能通过引用的方式找到它

- 通过右值引用的声明,该右值又“重获新生”,其生命周期与右值引用类型变量的生命周期一样

- 无论声明为右值引用还是左值引用都必须立即初始化

- 只有当发生自动类型推断时(如函数模板的类型自动推导,或auto关键字),&&才是一个universal references。

$移动语义 (move semantic)和完美转发 (perfect forwarding)

 

#std::move和std::forward

<https://www.jianshu.com/p/b90d1091a4ff<C++11 std::move和std::forward>>

[std::tuple&std::make_tuple]

<https://blog.csdn.net/sevenjoin/article/details/88420885<C++ tuple元组的基本用法(总结)>>

std::tuple<std::string, int, float> tp1("Sven Cheng", 77, 66.1);
std::string name;
int weight;
float f;
auto tp2 = std::make_tuple(std::ref(name), std::ref(weight), std::ref(f)) = tp1;

[emplace]

<https://blog.csdn.net/windpenguin/article/details/75581552<C++优化之使用emplace>>

<http://c.biancheng.net/view/6826.html<C++ STL vector添加元素(push_back()和emplace_back())详解>>

$vector

emplace <=>  insert

emplace_back​  <=> ​push_back

$set

emplcace <=>  insert

$map

emplace <=>  insert

 

[类的默认函数]

<https://www.cnblogs.com/lsgxeva/p/7668200.html<c++ 类的默认八种函数>>

1 默认构造函数

2 默认拷贝构造函数

3 默认析构函数

4 默认重载赋值运算符函数

5 默认重载取址运算符函数

6 默认重载取址运算符const函数

7 默认移动构造函数(C++11)

8 默认重载移动赋值操作符函数(C++11)

[type_traits(类型萃取)]

<https://www.cnblogs.com/5iedu/p/7767937.html<第17课 类型萃取(1)_基本的type_traits>>

<https://www.cnblogs.com/5iedu/p/7774833.html<第18课 类型萃取(2)_获取返回值类型的traits>>

<https://www.cnblogs.com/5iedu/p/7782291.html<第19课 类型萃取(3)_类型选择的traits>>

$type_traits类型萃取

(1)type_traits通过定义一些结构体或类,并利用模板类特化和偏特化的能力,给类型赋予一些特性,这些特性根据类型的不同而异。在程序设计中可以使用这些traits来判断一个类型的一些特性,引发C++的函数重载机制,实现同一种操作因类型不同而异的效果。

(2)type_traits提供了丰富的编译期计算、查询、判断、转换和选择的帮助类。

(3)type_traits的类型选择功能,在一定程序上可以消除冗长的switch-cast或if-else的语句。提高代码可维护性。type_traits的类型判断功能,在编译期可以检查出是否是正确的类型,以能编写更安全的代码。

//STL中的is_const的完整实现
template<class _Ty,
    _Ty _Val>
struct integral_constant
{   // convenient template for integral constant types
    static constexpr _Ty value = _Val;

    typedef _Ty value_type;
    typedef integral_constant<_Ty, _Val> type;

    constexpr operator value_type() const noexcept
    {   // return stored value
        return (value);
    }

    constexpr value_type operator()() const noexcept
    {   // return stored value
        return (value);
    }
};

typedef integral_constant<bool, true> true_type;
typedef integral_constant<bool, false> false_type;

template<class _Ty>
struct is_const
    : false_type
{   // determine whether _Ty is const qualified
};

template<class _Ty>
struct is_const<const _Ty>
    : true_type
{   // determine whether _Ty is const qualified
};
int main() {

    static_assert(is_const<int>::value,"error");//error
    static_assert(is_const<const int>::value, "error");//ok
    return 0;
}

[模板]

#数据类模板和模板类的特化

<https://www.cnblogs.com/dishengAndziyu/p/10919050.html#top<C++中的数据类模板>>

- 模板参数可以是数值型参数;

- 数值型模板参数必须在编译期间唯一确定;

- 数组类模板是基于数值型模板参数实现的;

- 数组类模板是简易的线性表数据结构;

//数值型模板
/* 用最高效的方法验证从 1 加到 n 的和;不用循环和等差数列求和公式 */
template< int N >
class Sum
{
public:
    static const int VALUE = Sum<N-1>::VALUE + N;  // 递归定义
};
 
/* 定义上述模板类的特化实现,实现递归出口 */
template< >
class Sum < 1 >
{
public:
    static const int VALUE = 1;
};
//
//数组模板类
template <typename T, int N>
class Array
{
    T a[N];  // 数组元素的类型和大小;
}
Array<double, 5> ad;  // 使用模板时,数值型参数必须是常量,不能是变量;

<https://blog.csdn.net/M_jianjianjiao/article/details/85220983<c++中模板的特化>>

<https://blog.csdn.net/lyn_00/article/details/83548629<C++模板 全特化、偏特化>>

$模板的特化

- 类模板和函数模板都可以被全特化;

- 类模板能偏特化,不能被重载;

- 函数模板能重载,不能被偏特化。

$模板调用优先级从高到低

全特化模板>偏特化模板(重载模板)>主版本模板

这样的优先级顺序对性能也是最好的。

#可变参数模板

<https://www.cnblogs.com/5iedu/p/7784721.html<初识参数包>>

<https://www.cnblogs.com/5iedu/p/7787302.html<展开参数包>>

<https://www.cnblogs.com/5iedu/p/7818875.html<深入理解参数包>>

$初识参数包

- 模板参数包(以tuple为例):template<typename… Elements>class tuple

- 函数参数包:如template<typename…T> void f(T…args)

- 省略号“…”

01 当声明一个变量(或标识符)为可变参数时(即变量是一个形参),省略号位于该变量的左侧。

02 当使用参数包时(即变量作为实参),省略号位于参数名称的右侧,表示立即展开该参数,这个过程也被称为解包。

- 包扩展表达式“exp…”相当于将省略号左侧的参数包exp(可能是个变量或表达式)视为一个整体来进行扩展。

$展开参数包

- 可变模板参数不能直接作为变量保存起来,需要借助tuple保存起来。

[lambda]

<https://www.cnblogs.com/jimodetiantang/p/9016826.html<C++之Lambda表达式>>

Lambda 的语法形式如下:

[函数对象参数] (操作符重载函数参数) mutable 或 exception 声明 -> 返回值类型 {函数体}

 

$栈或堆中定义方式

auto my_lambda_func = [&](int x) { /* ... */ };

auto my_onheap_lambda_func = new auto([=](int x) { /* ... */ });

 

$lambda函数内部是如何工作的?

[异常(exception noexcecpt)]

$函数的异常说明

<https://blog.csdn.net/cbs612537/article/details/8117415<C++异常之异常说明>>

- 异常说明 进行对一个函数的异常进行说明, 如果函数抛出异常,被抛出的异常将是包含在该说明中的一种或是从列出的异常中派生的类型。

- 编译器不会对异常说明进行检测,异常说明更多的是写给函数的用户看。

$noexcecpt

<https://www.cnblogs.com/sword03/p/10020344.html<C++11 带来的新特性 (3)—— 关键字noexcept>>

该关键字告诉编译器,函数中不会发生异常,这有利于编译器对程序做更多的优化。

如果在运行时,noexecpt函数向外抛出了异常(如果函数内部捕捉了异常并完成处理,这种情况不算抛出异常),程序会直接终止,调用std::terminate()函数,该函数内部会调用std::abort()终止程序。

// 在新版本的编译器中,析构函数是默认加上关键字noexcept的,可以使用noexcept(false)去取消。下面代码可以检测编译器是否给析构函数加上关键字noexcept
struct X
{
    ~X() { };
};
int main()
{
    X x;
    static_assert(noexcept(x.~X()), "Ouch!");
}

[RAII]

<https://blog.csdn.net/10km/article/details/49847271<C++11实现模板化(通用化)RAII机制>>

$什么是RAII?

RAII(Resource Acquisition Is Initialization),也称直译为“资源获取就是初始化”,是C++语言的一种管理资源、避免泄漏的机制。

C++标准保证任何情况下,已构造的对象最终会销毁,即它的析构函数最终会被调用。

RAII 机制就是利用了C++的上述特性,在需要获取使用资源RES的时候,构造一个临时对象(T),在其构造T时获取资源,在T生命期控制对RES的访问使之始终保持有效,最后在T析构的时候释放资源。以达到安全管理资源对象,避免资源泄漏的目的。

 

[智能指针]

<https://blog.csdn.net/GangStudyIT/article/details/80645399<C++中的三种智能指针分析(RAII思想)>>

<https://www.cnblogs.com/wangshaowei/p/9374389.html<C++11学习之share_ptr和weak_ptr>>

$性能

- 因为 C++的 zero cost abstraction 的特点,unique_ptr 在默认情况下和裸指针的大小是一样的。所以内存上没有任何的额外消耗,性能是最优的。

- 因为 C++的 zero cost abstraction 的特点,unique_ptr 在默认情况下和裸指针的大小是一样的。所以内存上没有任何的额外消耗,性能是最优的。

内存占用高。 - shared_ptr 的内存占用是裸指针的两倍。因为除了要管理一个裸指针外,还要维护一个引用计数。因此相比于- unique_ptr, shared_ptr 的内存占用更高

原子操作性能低。 考虑到线程安全问题,引用计数的增减必须是原子操作。而原子操作一般情况下都比非原子操作慢。

使用移动优化性能。shared_ptr 在性能上固然是低于 unique_ptr。而通常情况,我们也可以尽量避免 shared_ptr 复制。如果,一个 shared_ptr 需要将所有权共享给另外一个新的 shared_ptr,而我们确定在之后的代码中都不再使用这个 shared_ptr

$weak_ptr的作用(避免智能指针互相引用,导致内存泄漏)

class Parent

{

public:

    shared_ptr<Child> child;

};

class Child

{

public:

    shared_ptr<Parent> parent;

};

shared_ptr<Parent> pA(new Parent);

shared_ptr<Child> pB(new Child);

pA->child = pB;

pB->parent = pA;

那么这是一个非常鲜明的移动语义。对于此种场景,我们尽量使用 std::move,将 shared_ptr 转移给新的对象。因为移动不用增加引用计数,因此性能比复制更好。

 

#shared_ptr线程安全性分析

<https://blog.csdn.net/jiangfuqiang/article/details/8292906<shared_ptr线程安全性分析>>

<https://blog.csdn.net/iteye_11790/article/details/82475025<为什么多线程读写 shared_ptr 要加锁?>>

#shared_from_this

<https://zhuanlan.zhihu.com/p/92815756>

我们往往会需要在类内部使用自身的 shared_ptr,例如:

 

class Widget

{

public:

 void do_something(A& a)

 {

 a.widget = 该对象的shared_ptr;

 }

}

我们需要把当前 shared_ptr 对象同时交由对象 a 进行管理。意味着,当前对象的生命周期的结束不能早于对象 a。因为对象 a 在析构之前还是有可能会使用到a.widget。

 

如果我们直接a.widget = this;, 那肯定不行, 因为这样并没有增加当前 shared_ptr 的引用计数。shared_ptr 还是有可能早于对象 a 释放。

 

如果我们使用a.widget = std::make_shared<Widget>(this);,肯定也不行,因为这个新创建的 shared_ptr,跟当前对象的 shared_ptr 毫无关系。当前对象的 shared_ptr 生命周期结束后,依然会释放掉当前内存,那么之后a.widget依然是不合法的。

 

对于这种,需要在对象内部获取该对象自身的 shared_ptr, 那么该类必须继承std::enable_shared_from_this<T>。代码如下:

 

class Widget : public std::enable_shared_from_this<Widget>

{

public:

 void do_something(A& a)

 {

 a.widget = shared_from_this();

 }

}

这样才是合法的做法。

 

 

 

### 回答1: 对于学习 qt 知识点整理思维导图非常有帮助。首先,思维导图可以帮助我们梳理 qt 的知识结构,帮助我们建立起一个清晰的知识体系。我们可以将 qt 的主要知识点作为中心思维节点,在周围分支出各个具体的知识点,形成一个完整的思维导图。这样,我们可以清楚地看到每个知识点之间的关系和联系,更好地理解 qt 的整体架构和工作原理。 其次,思维导图可以帮助我们更好地记忆和复习 qt 的知识点。通过在思维导图中加入关键词、示意图和简单的说明,我们可以将 qt 的知识点以一种直观的方式呈现出来。这样,在复习的时候,我们可以随时查看思维导图,回忆起相关的知识点,加深记忆。同时,思维导图可以帮助我们发现知识点之间的遗漏或者薄弱之处,有助于我们有针对性地进行重点复习。 最后,思维导图还可以帮助我们提高问题解决能力。在学习 qt 的过程中,我们遇到问题时可以将问题写在思维导图中,并找到与之相关的知识点。通过思考和整理,我们可以更深入地理解问题的本质和解决方法,提高自己的问题解决能力。 综上所述,使用思维导图学习 qt 知识点非常有效。它可以帮助我们梳理知识结构、加深记忆、提高问题解决能力,是我们学习 qt 不可或缺的工具之一。 ### 回答2: Qt是一个跨平台的C++应用程序开发框架,广泛应用于图形界面应用程序的开发。学习Qt时,整理思维导图是一种很好的学习方法。 首先,在思维导图中,我会列出Qt的基本概念和核心模块,包括信号和槽机制、窗口和控件、布局管理、事件处理等。了解这些基本概念可以帮助我建立起对Qt框架的整体认识。 接下来,我会将Qt框架中常用的模块和类进行分组,如图形界面相关的模块(如QWidgets、QPainter、QPixmap等),文件操作相关的模块(如QFile、QDir等),网络通信相关的模块(如QTcpSocket、QUdpSocket等),数据库操作相关的模块(如QSqlDatabase、QSqlQuery等)等。这样做可以让我更清晰地了解Qt框架中各个部分的功能和作用。 在每个模块中,我会进一步细分各个类的功能和使用方法,并在思维导图中进行标注。比如,对于QWidgets模块,我可以列举出常用的窗口类(如QMainWindow、QDialog等)和控件类(如QPushButton、QLineEdit等),并在其旁边注明它们的作用和常用的函数。 此外,在思维导图中,我还可以加入一些示例代码和链接,以加深对Qt知识点的理解和掌握。这样一来,我在学习Qt的过程中,可以通过查阅思维导图来对各个知识点进行回顾和巩固。 总的来说,用思维导图整理Qt知识点可以使我更加系统地学习和掌握Qt框架。将各个知识点有机地结合在一起,形成一个完整的思维导图,有助于我在实际应用开发中更加灵活和高效地运用Qt技术。 ### 回答3: QT是一种跨平台应用程序开发工具,它具有丰富的库和组件,可以帮助开发者快速创建图形用户界面和实现功能丰富的应用程序。学习QT时,可以使用思维导图进行知识点整理,以帮助我们更好地理解和记忆内容。 首先,在思维导图的中心,可以写上"QT"这个关键词,作为整个思维导图的核心。然后,可以根据QT的主要功能和特点,将知识点分为以下几个方面进行整理: 1. QT基础知识:首先要了解QT的基本概念和架构,比如QT的版本、主要组件等。可以列出QT的基本特点,如跨平台性、开源性等。 2. QT的常用类和模块:在思维导图的下方,可以列出QT的常用类和模块,包括QWidget、QLayout、QLabel、QPushButton等,以及常用的模块如图形、网络、数据库等。可以进一步展开每个类和模块,记录它们的特点和示例用法。 3. QT的信号与槽机制:QT的信号与槽机制是其重要的特性之一,可以通过思维导图来详细介绍这个机制的原理和使用方法。可以展示信号和槽的连接方式、参数的传递等。 4. QT的图形用户界面设计:QT提供了丰富的图形用户界面设计工具,如Qt Designer,可以在思维导图中列出图形用户界面设计的基本步骤和注意事项,比如窗口布局、控件的选择和使用等。 5. QT的常用功能和技巧:在思维导图的边缘,可以列出一些常用的QT功能和技巧,如界面国际化、线程处理、文件操作等。可以进一步展开每个功能和技巧,记录其实现方法和使用场景。 通过思维导图的整理学习,可以清晰地掌握QT的核心知识点,有助于开发者更好地理解和运用QT进行应用程序开发。同时,思维导图也可以帮助我们进行知识的巩固和复习,提高学习效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值