c++11

文章目录

c++11基础知识点

初始化,一切皆可{}初始化,并且可以不加=符号

bash 复制代码
#include <iostream>
using namespace std;

class Point
{
public:
    Point(int x, int y)
        : _x(x), _y(y)
    {
        cout << "构造函数" << endl;
    }

    ~Point()
    {
    }

private:
    int _x;
    int _y;
};

int main()
{
    int x = 1;
    int y = {1};
    int z{1};

    int a1[] = {1, 2, 3, 4, 5};
    int a2[]{1, 2, 3, 4, 5};

    Point n1(1, 1);
    Point n2 = {1, 1}; //多参数的隐式类型转换 加explicit就不能转换了
    Point n3{2, 2};

    int *ptr1 = new int[3]{1, 2, 3};
    Point *n4 = new Point[2]{{1, 1}, {2, 2}};
    return 0;
}
复制代码

initializer_list容器

c 复制代码
//c++11中 {10,20,30}这是一个常量数组,被放在常量区

template <class T>
class initializer_list
{
	const T* _start;
    const T* _finish;
}
//这两个指针分别指向常量区的首部,和最后一个元素的下一个位置。


vector<int> v1 = {1,2,3,4,5}  //这后面的列表也是一个initialzer_list,vector的构造函数实现了参数是initalizer_list类型的构造

//vector内部其实是这样实现构造的
vector(initializer_list<value_type> il)
{
    reserve(il.size());
    for(auto& e:il)
    {
        push_back(e);
    }
}

decltype

c 复制代码
int i = 1;
auto f = &i;
auto pf = malloc;

cout<<typeid(f).name()<<endl;
cout<<typeid(pf).namej()<<endl;

decltype(pf) pf2;

//typeid推出类型只是一个字符串,只能看不能用
//decltype退出对象的类型,可以定义变量,后者作为模板实参

array

对标的是静态数组,指针解引用,数组越界的情况。

c 复制代码
int mian()
{
    int a[10] = {1,2,3,4,5,6,7,8,9,10};
   	array<int,10> aty = {1,2,3,4,5,6};
    a[15] = 1; //指针的解引用
    aty[15] = 2; //operator[] 函数的调用,内部检查
    return 0; 
}

forward_list

就是一个单链表,单项迭代器

可变模板参数

原理

c 复制代码
template<class T> 
void ShowList(T value)
{
    //结束条件的函数
	cout << value << endl;
}
template <class T,class ...Args>
void ShowList(T value, Args... args)
{
	cout << value << endl;
	ShowList(args...);
}

使用的是编译时递归,而不是采用c语言的方式,并没有把每一个参数都存储起来。

实际用途

c 复制代码
class Date
{
public:
	Date(int year = 1, int month = 1, int day = 1)
		:_month(month)
		, _year(year)
		, _day(day)
	{

	}
private:
	int _month;
	int _year;
	int _day;
};
template<class ...Args>
Date* Create(Args... args)
{
	Date* ret = new Date(args...);

	return ret;
}
int main()
{
	Date* A = Create(2001,11,4);
	Date* B = Create(A);//甚至传递类也是可以的,调用的是拷贝构造
	return 0;
}

emplace

原理:

c 复制代码
int main()
{
    std::list<std::pair<int,string>> mylist;
    mylist.emplace_back(10,"soct");//这里底层调用的是构造函数
    mylist.emplace_back(make_pair(10,"sock"));//这里底层用的是拷贝构造。
    
    mylist.push_back(make_pair(30,"sort"));//这里是移动构造
    mylist.push_back({40,"sort"}); //这里是移动构造 
    return 0;
}

可以接受参数包用于原地构造对象,也可以接受已经构造好的对象。

参数包:

emplace 系列接口使用了可变参数模板(variadic templates),因此你可以直接传递多个参数来调用对象的构造函数,这允许你直接在容器的内存中构造对象,而不需要先创建临时对象。

已经构造好的对象:

即使你传递的是一个已经构造好的对象,emplace 系列接口仍然会尽可能避免不必要的拷贝或移动操作。具体来说,传递一个对象时,emplace 会利用移动构造函数(如果有),否则会使用拷贝构造函数。

示例:

传递参数包:
cpp 复制代码
#include <iostream>
#include <vector>

class MyClass {
public:
    MyClass(int x, double y) {
        std::cout << "Constructor called with x = " << x << ", y = " << y << std::endl;
    }
};

int main() {
    std::vector<MyClass> vec;
    
    // 使用 emplace_back 传递参数包构造对象
    vec.emplace_back(10, 20.5);  // 直接调用 MyClass(int, double) 构造函数
    
    return 0;
}

输出

复制代码
Constructor called with x = 10, y = 20.5
传递对象:
cpp 复制代码
#include <iostream>
#include <vector>

class MyClass {
public:
    MyClass(int x, double y) {
        std::cout << "Constructor called with x = " << x << ", y = " << y << std::endl;
    }

    MyClass(const MyClass& other) {
        std::cout << "Copy constructor called" << std::endl;
    }

    MyClass(MyClass&& other) noexcept {
        std::cout << "Move constructor called" << std::endl;
    }
};

int main() {
    std::vector<MyClass> vec;

    MyClass obj(30, 40.5);  // 创建一个对象

    // 使用 emplace_back 传递已经构造好的对象
    vec.emplace_back(obj);  // 这里会调用拷贝构造函数
    vec.emplace_back(std::move(obj));  // 这里会调用移动构造函数
    
    return 0;
}

输出

复制代码
Constructor called with x = 30, y = 40.5
Copy constructor called
Move constructor called

总结:

  • 参数包emplace 系列接口可以传递多个参数,这些参数会被传递给对象的构造函数以在容器中直接构造对象,避免了构造临时对象然后移动或拷贝的开销。
  • 传递对象 :如果你传递一个已经构造好的对象,emplace 会尽量调用移动构造函数(如果对象是通过 std::move 传递的),否则调用拷贝构造函数。

emplace 系列接口的优势在于它可以灵活处理不同类型的参数传递方式,从而减少性能损耗,尤其是避免了不必要的拷贝或移动操作。

相关推荐
2的n次方_3 小时前
CANN Ascend C 编程语言深度解析:异构并行架构、显式存储层级与指令级精细化控制机制
c语言·开发语言·架构
近津薪荼3 小时前
dfs专题5——(二叉搜索树中第 K 小的元素)
c++·学习·算法·深度优先
xiaoye-duck3 小时前
吃透 C++ STL list:从基础使用到特性对比,解锁链表容器高效用法
c++·算法·stl
_F_y3 小时前
C++重点知识总结
java·jvm·c++
java干货4 小时前
为什么 “File 10“ 排在 “File 2“ 前面?解决文件名排序的终极算法:自然排序
开发语言·python·算法
_F_y4 小时前
C语言重点知识总结(含KMP详细讲解)
c语言·开发语言
毕设源码-郭学长4 小时前
【开题答辩全过程】以 基于python的二手房数据分析与可视化为例,包含答辩的问题和答案
开发语言·python·数据分析
无小道4 小时前
Qt——常用控件
开发语言·qt
aini_lovee4 小时前
MATLAB基于小波技术的图像融合实现
开发语言·人工智能·matlab
R1nG8634 小时前
多线程安全设计 CANN Runtime关键数据结构的锁优化
开发语言·cann