C++ STL array 容器(深入了解,一文学会)

2023-10-29

        array 容器是 C++ 11 标准中新增的序列容器,简单地理解,它就是在 C++ 普通数组的基础上,添加了一些成员函数和全局函数。在使用上,它比普通数组更安全,且效率并没有因此变差。和其它容器不同,array 容器的大小是固定的,无法动态的扩展或收缩,这也就意味着,在使用该容器的过程无法借由增加或移除元素而改变其大小,它只允许访问或者替换存储的元素。

        C++ 11 标准库还新增加了 begin() 和 end() 这 2 个函数,和 array 容器包含的 begin() 和 end() 成员函数不同的是,标准库提供的这 2 个函数的操作对象,既可以是容器,还可以是普通数组。当操作对象是容器时,它和容器包含的 begin() 和 end() 成员函数的功能完全相同;如果操作对象是普通数组,则 begin() 函数返回的是指向数组第一个元素的指针,同样 end() 返回指向数组中最后一个元素之后一个位置的指针(注意不是最后一个元素)。另外,在 <array> 头文件中还重载了 get() 全局函数,该重载函数的功能是访问容器中指定的元素,并返回该元素的引用。

        正是由于 array 容器中包含了 at() 这样的成员函数,使得操作元素时比普通数组更安全。

   本文作者原创,转载请附上文章出处与本文链接。

C++ STL array 容器(深入了解,一文学会)目录

1 array容器的成员函数

2 array容器初始化

3 array容器部分成员函数的用法和功能

4 array迭代器的成员函数

5 array 容器正向迭代&&反向迭代

5.1 array 两种正向迭代

5.1.1 begin()/end()

5.1.2 cbegin()/cend()

5.2 array 反向迭代器

6 访问array容器中单个元素

7 访问array容器中多个元素

7.1 访问array容器中单个元素

7.2 访问array容器中多个元素

8 array容器和普通数组

8.1 类型相同的array容器

8.2 大小相同的array容器

8.3 类型大小都相同的array容器


1 array容器的成员函数

成员函数 功能
begin() 返回指向容器中第一个元素的随机访问迭代器。
end() 返回指向容器最后一个元素之后一个位置的随机访问迭代器,通常和 begin() 结合使用。
rbegin() 返回指向最后一个元素的随机访问迭代器。
rend() 返回指向第一个元素之前一个位置的随机访问迭代器。
cbegin() 和 begin() 功能相同,只不过在其基础上增加了 const 属性,不能用于修改元素。
cend() 和 end() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改元素。
crbegin() 和 rbegin() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改元素。
crend() 和 rend() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改元素。
size() 返回容器中当前元素的数量,其值始终等于初始化 array 类的第二个模板参数 N。
max_size() 返回容器可容纳元素的最大数量,其值始终等于初始化 array 类的第二个模板参数 N。
empty() 判断容器是否为空,和通过 size()==0 的判断条件功能相同,但其效率可能更快。
at(n) 返回容器中 n 位置处元素的引用,该函数自动检查 n 是否在有效的范围内,如果不是则抛出 out_of_range 异常。
front() 返回容器中第一个元素的直接引用,该函数不适用于空的 array 容器。
back() 返回容器中最后一个元素的直接应用,该函数同样不适用于空的 array 容器。
data() 返回一个指向容器首个元素的指针。利用该指针,可实现复制容器中所有元素等类似功能。
fill(val) 将 val 这个值赋值给容器中的每个元素。
array1.swap(array2) 交换 array1 和 array2 容器中的所有元素,但前提是它们具有相同的长度和类型。

2 array容器初始化

.h 

#include <array>
using namespace std;

.cpp

//创建具有 10 个 double 类型元素的 array 容器
array<double, 10> values;

//对元素进行初始化
array<double, 10> values {0.5,1.0,1.5,,2.0};

3 array容器部分成员函数的用法和功能

	array<int, 4> values{};
	//初始化 values 容器为 {0,1,2,3}
	for (int i = 0; i < values.size(); i++) {
		values.at(i) = i;
	}
	//使用 get() 重载函数输出指定位置元素
	//get<3>(values)	//3


	//如果容器不为空,则输出容器中所有的元素
	if (!values.empty()) {
		for (auto val = values.begin(); val < values.end(); val++) {
			cout << *val << " ";
		}
	}
	//0 1 2 3

4 array迭代器的成员函数

成员函数 功能
begin() 返回指向容器中第一个元素的正向迭代器;如果是 const 类型容器,在该函数返回的是常量正向迭代器。
end() 返回指向容器最后一个元素之后一个位置的正向迭代器;如果是 const 类型容器,在该函数返回的是常量正向迭代器。此函数通常和 begin() 搭配使用。
rbegin() 返回指向最后一个元素的反向迭代器;如果是 const 类型容器,在该函数返回的是常量反向迭代器。
rend() 返回指向第一个元素之前一个位置的反向迭代器。如果是 const 类型容器,在该函数返回的是常量反向迭代器。此函数通常和 rbegin() 搭配使用。
cbegin() 和 begin() 功能类似,只不过其返回的迭代器类型为常量正向迭代器,不能用于修改元素。
cend() 和 end() 功能相同,只不过其返回的迭代器类型为常量正向迭代器,不能用于修改元素。
crbegin() 和 rbegin() 功能相同,只不过其返回的迭代器类型为常量反向迭代器,不能用于修改元素。
crend() 和 rend() 功能相同,只不过其返回的迭代器类型为常量反向迭代器,不能用于修改元素。

C++ 11 标准新增的 begin() 和 end() 函数,当操作对象为 array 容器时,也和迭代器有关,其功能分别和下图中的 begin()、end() 成员函数相同

 根据它们的功能并结合实际场景的需要,这些成员函数通常是成对使用的,即 begin()/end()、rbegin()/rend()、cbegin()/cend()、crbegin()/crend() 各自成对搭配使用。不仅如此,这 4 对中 begin()/end() 和 cbegin()/cend()、rbegin()/rend() 和 crbegin()/crend() 的功能大致是相同的(如上图所示),唯一的区别就在于其返回的迭代器能否用来修改元素值。

值得一提的是,以上函数在实际使用时,其返回值类型都可以使用 auto 关键字代替,编译器可以自行判断出该迭代器的类型。

5 array 容器正向迭代&&反向迭代

5.1 array 两种正向迭代

5.1.1 begin()/end()

        array 容器模板类中的 begin() 和 end() 成员函数返回的都是正向迭代器,它们分别指向「首元素」和「尾元素+1」 的位置。在实际使用时,我们可以利用它们实现初始化容器或者遍历容器中元素的操作。可以在循环中显式地使用迭代器来初始化 values 容器的值

array<int, 5>values;
int h = 1;
auto first = values.begin();
auto last = values.end();
//初始化 values 容器为{1,2,3,4,5}
while (first != last)
{
	*first = h;
	++first;
	h++;
}

//正向迭代
first = values.begin();
while (first != last)
{
	cout << *first << " ";
	++first;
}

//1 2 3 4 5

可以看出,迭代器对象是由 array 对象的成员函数 begin() 和 end() 返回的。我们可以像使用普通指针那样上使用迭代器对象。比如代码中,在保存了元素值后,使用前缀 ++ 运算符对 first 进行自增,当 first 等于 end 时,所有的元素都被设完值,循环结束。与此同时,还可以使用全局的 begin() 和 end() 函数来从容器中获取迭代器,因为当操作对象为 array 容器时,它们和 begin()/end() 成员函数是通用的。所以上面代码中,first 和 last 还可以像下面这样定义:

auto first = std::begin(values);
auto last = std::end (values);

5.1.2 cbegin()/cend()

array 模板类还提供了 cbegin() 和 cend() 成员函数,它们和 begin()/end() 唯一不同的是,前者返回的是 const 类型的正向迭代器,这就意味着,有 cbegin() 和 cend() 成员函数返回的迭代器,可以用来遍历容器内的元素,也可以访问元素,但是不能对所存储的元素进行修改

array<int, 5>values{ 1,2,3,4,5 };
int h = 1;
auto first = values.cbegin();
auto last = values.cend();

//由于 *first 为 const 类型,不能用来修改元素
//*first = 10;

//遍历容器并输出容器中所有元素
while (first != last)
{
	//可以使用 const 类型迭代器访问元素
	cout << *first << " ";
	++first;
}

//1 2 3 4 5

此程序的*first = 10中,我们尝试使用 first 迭代器修改 values 容器中的值,如果取消注释并运行此程序,编译器会提示你“不能给常量赋值”,即 *first 是 const 类型常量,所以这么做是不对的。但是遍历并访问容器的行为,是允许的。

5.2 array 反向迭代器

        array 模板类中还提供了 rbegin()/rend() 和 crbegin()/crend() 成员函数,它们每对都可以分别得到指向最一个元素和第一个元素前一个位置的随机访问迭代器,又称它们为反向迭代器。

需要注意的是,在使用反向迭代器进行 ++ 或 -- 运算时,++ 指的是迭代器向左移动一位,-- 指的是迭代器向右移动一位,即这两个运算符的功能也“互换”了。

array<int, 5>values;
int h = 1;
auto first = values.rbegin();
auto last = values.rend();
//初始化 values 容器为 {5,4,3,2,1}    //rbegin 反向插入
while (first != last)
{
	*first = h;
	++first;
	h++;
}
//重新遍历容器,并输入各个元素
first = values.rbegin();
while (first != last)
{
	cout << *first << " ";
	++first;
}

/*
    for (auto first = values.rbegin(); first != values.rend(); ++first) {
        cout << *first << " ";
    }
*/
//1 2 3 4 5

可以看到,从最后一个元素开始循环,不仅完成了容器的初始化,还遍历输出了容器中的所有元素。结束迭代器指向第一个元素之前的位置,所以当 first 指向第一个元素并 +1 后,循环就结朿了。

在反向迭代器上使用 ++ 递增运算符,会让迭代器用一种和普通正向迭代器移动方向相反的方式移动。

crbegin()/crend() 组合和 rbegin()/crend() 组合的功能唯一的区别在于,前者返回的迭代器为 const 类型,即不能用来修改容器中的元素,除此之外在使用上和后者完全相同。

6 访问array容器中单个元素

可以通过容器名[]的方式直接访问和使用容器中的元素,这和普通数组访问元素的方式相同

values[4] = values[3] + 2.O*values[1];

此行代码中,第 5 个元素的值被赋值为右边表达式的值。需要注意的是,使用如上这样方式,由于没有做任何边界检查,所以即便使用越界的索引值去访问或存储元素,也不会被检测到。

为了能够有效地避免越界访问的情况,可以使用 array 容器提供的 at() 成员函数,例如 :

values.at (4) = values.at(3) + 2.O*values.at(1);

这行代码和前一行语句实现的功能相同,其次当传给 at() 的索引是一个越界值时,程序会抛出 std::out_of_range 异常。因此当需要访问容器中某个指定元素时,建议大家使用 at(),除非确定索引没有越界。

读者可能有这样一个疑问,即为什么 array 容器在重载 [] 运算符时,没有实现边界检查的功能呢?答案很简单,因为性能。如果每次访问元素,都去检查索引值,无疑会产生很多开销。当不存在越界访问的可能时,就能避免这种开销。

除此之外,array 容器还提供了 get<n> 模板函数,它是一个辅助函数,能够获取到容器的第 n 个元素。需要注意的是,该模板函数中,参数的实参必须是一个在编译时可以确定的常量表达式,所以它不能是一个循环变量。也就是说,它只能访问模板参数指定的元素,编译器在编译时会对它进行检查。

下面代码展示了如何使用 get<n> 模板函数:

#include <iostream>
#include <array>
#include <string>
using namespace std;
int main()
{
	array<string, 5> words{ "one","two","three","four","five" };
	cout << get<3>(words) << endl; // Output words[3]
	//cout << get<6>(words) << std::endl; //越界,会发生编译错误
	return 0;
}

//four

array 容器提供了 data() 成员函数,通过调用该函数可以得到指向容器首个元素的指针。通过该指针,我们可以获得容器中的各个元素


#include <iostream>
#include <array>
using namespace std;
int main()
{
	array<int, 5> words{ 1,2,3,4,5 };
	cout << *(words.data() + 1);
	return 0;
}

// 2

7 访问array容器中多个元素

        当 array 容器创建完成之后,最常做的操作就是获取其中的元素,甚至有时还会通过循环结构获取多个元素。

7.1 访问array容器中单个元素

        可以通过容器名[]的方式直接访问和使用容器中的元素,这和 C++ 标准数组访问元素的方式相同

array<int, 5> words{ 1,2,3,4,5 };

words[4] = words[8];

        上面代码中,第 8个元素的值被赋值为左边表达式的值。需要注意的是,使用如上这样方式,由于没有做任何边界检查,所以即便使用越界的索引值去访问或存储元素,也不会被检测到。运行会直接弹出错误。

为了能够有效地避免越界访问的情况,可以使用 array 容器提供的 at() 成员函数,例如 :

array<int, 5> words{ 1,2,3,4,5 };

try
{
	words.at(4) = words.at(8);
}
catch (const std::exception&)
{
	AfxMessageBox("出现异常");
}

        这行代码和前一行语句实现的功能相同,其次当传给 at() 的索引是一个越界值时,程序会抛出 std::out_of_range 异常。因此当需要访问容器中某个指定元素时,建议大家使用 at(),除非确定索引没有越界。

读者可能有这样一个疑问,即为什么 array 容器在重载 [] 运算符时,没有实现边界检查的功能呢?答案很简单,因为性能。如果每次访问元素,都去检查索引值,无疑会产生很多开销。当不存在越界访问的可能时,就能避免这种开销。

        除此之外,array 容器还提供了 get<n> 模板函数,它是一个辅助函数,能够获取到容器的第 n 个元素。需要注意的是,该模板函数中,参数的实参必须是一个在编译时可以确定的常量表达式,所以它不能是一个循环变量。也就是说,它只能访问模板参数指定的元素,编译器在编译时会对它进行检查。

    array<string, 5> words{ "one","two","three","four","five" };
    cout << get<3>(words) << endl; // Output words[3]
    //cout << get<6>(words) << std::endl; //越界,会发生编译错误

        array 容器提供了 data() 成员函数,通过调用该函数可以得到指向容器首个元素的指针。通过该指针,我们可以获得容器中的各个元素,例如:

    array<int, 5> words{1,2,3,4,5};
    cout << *( words.data()+1);

7.2 访问array容器中多个元素

        array 容器提供的 size() 函数能够返回容器中元素的个数(函数返回值为 size_t 类型)

array<int, 5> values{ 1,2,3,4,5 };

size_t i = values.size();

         通过调用 array 容器的 empty() 成员函数,即可知道容器中有没有元素(如果容器中没有元素,此函数返回 true)

array<int, 5> values{ 1,2,3,4,5 };

if (values.empty())
	AfxMessageBox("The container has no elements.");
else
	AfxMessageBox("The container has elements.");

         很少会创建空的 array 容器,因为当生成一个 array 容器时,它的元素个数就固定了,而且无法改变,所以生成空 array 容器的唯一方法是将模板的第二个参数指定为 0,但这种情况基本不可能发生。

array 容器之所以提供 empty() 成员函数的原因,对于其他元素可变或者元素可删除的容器(例如 vector、deque 等)来说,它们使用 empty() 时的机制是一样的,因此为它们提供了一个一致性的操作。

除了借助 size() 外,对于任何可以使用迭代器的容器,都可以使用基于范围的循环,因此能够更加简便地计算容器中所有元素的和,比如:

    double total = 0;
    for(auto&& value : values)
        total += value;

总结:

    #include <iostream>
    #include <iomanip> 
    #include <array>
    using namespace std;
    int main()
    {
        array<int, 5> values1;
        array<int, 5> values2;
        //初始化 values1 为 {0,1,2,3,4}
        for (size_t i = 0; i < values1.size(); ++i)
        {
            values1.at(i) = i;
        }
        cout << "values1[0] is : " << values1[0] << endl;
        cout << "values1[1] is : " << values1.at(1) << endl;
        cout << "values1[2] is : " << get<2>(values1) << endl;
        //初始化 values2 为{10,11,12,13,14}
        int initvalue = 10;
        for (auto& value : values2)
        {
            value = initvalue;
            initvalue++;
        }
        cout <<  "Values1 is : ";
        for (auto i = values1.begin(); i < values1.end(); i++) {
            cout << *i << " ";
        }
        cout << endl << "Values2 is : ";
        for (auto i = values2.begin(); i < values2.end(); i++) {
            cout << *i << " ";
        }
        return 0;
    }

// 输出
values1[0] is : 0
values1[1] is : 1
values1[2] is : 2
Values1 is : 0 1 2 3 4
Values2 is : 10 11 12 13 14

8 array容器和普通数组

        和 C++ 普通数组存储数据的方式一样,C++ 标准库保证使用 array 容器存储的所有元素一定会位于连续且相邻的内存中

    array<int, 5>a{1,2,3};
    cout << &a[2] << " " << &a[0] + 2 << endl;
    
    //输出结果为:  004FFD58 004FFD58

    strcpy(&a[0], "csdn");
    strcpy(a.data(), "csdn");

可以看到,a 容器中 &a[2] 和 &a[0] + 2 是相等的。因此在实际编程过程中,我们完全有理由去尝试,在原本使用普通数组的位置,改由 array 容器去实现。

用 array 容器替换普通数组的好处是,array 模板类中已经封装好了大量实用的方法,在提高开发效率的同时,代码的运行效率也会大幅提高。

注意,array 容器的大小必须保证能够容纳复制进来的数据,而且如果是存储字符串的话,还要保证在存储整个字符串的同时,在其最后放置一个\0作为字符串的结束符。此程序中,strcpy() 在拷贝字符串的同时,会自动在最后添加\0

8.1 类型相同的array容器

        用 array 容器代替普通数组,最直接的好处就是 array 模板类中已经为我们写好了很多实用的方法,可以大大提高我们编码效率。例如,array 容器提供的 at() 成员函数,可以有效防止越界操纵数组的情况;fill() 函数可以实现数组的快速初始化;swap() 函数可以轻松实现两个相同数组(类型相同,大小相同)中元素的互换。

8.2 大小相同的array容器

        当两个 array 容器满足大小相同并且保存元素的类型相同时,两个 array 容器可以直接直接做赋值操作,即将一个容器中的元素赋值给另一个容器

8.3 类型大小都相同的array容器

        如果其保存的元素也支持比较运算符,就可以用任何比较运算符直接比较两个 array 容器。

    array<char, 50>addr1{"csdn"};
    array<char, 50>addr2{ "csdn_断点" };

    //addr1 = addr2;    当两个 array 容器满足大小相同并且保存元素的类型相同时,两个 array 容器可以直接直接做赋值操作,即将一个容器中的元素赋值给另一个容器。
    addr1.swap(addr2);

    printf("addr1 is:%s\n", addr1.data());
    printf("addr2 is:%s\n", addr2.data());



    array<char, 50>addr1{ "csdn" };
    array<char, 50>addr2{ "csdn_断点" };
    if (addr1 == addr2) {
        std::cout << "addr1 == addr2" << std::endl;
    }
    if (addr1 < addr2) {
        std::cout << "addr1 < addr2" << std::endl;
    }
    if (addr1 > addr2) {
        std::cout << "addr1 > addr2" << std::endl;
    }

        两个容器比较大小的原理,和两个字符串比较大小是一样的,即从头开始,逐个取两容器中的元素进行大小比较(根据 ASCII 码表),直到遇到两个不相同的元素,那个元素的值大,则该容器就大。

        总之,读者可以这样认为,array 容器就是普通数组的“升级版”,使用普通数组能实现的,使用 array 容器都可以实现,而且无论是代码功能的实现效率,还是程序执行效率,都比普通数组更高。

以下博客部分内容借鉴自:http://c.biancheng.net/stl/。

C++ STL 容器、迭代器、适配器(深入了解,一文学会)    https://blog.csdn.net/qq_37529913/article/details/120052137                                                                                C++ STL deque容器(深入了解,一文学会)                       https://blog.csdn.net/qq_37529913/article/details/118676574
C++ STL vector容器(深入了解,一文学会)                       https://blog.csdn.net/qq_37529913/article/details/118676109
C++ STL list容器(深入了解,一文学会)                             https://blog.csdn.net/qq_37529913/article/details/118676917
C++ STL forward_list容器(深入了解,一文学会)               https://blog.csdn.net/qq_37529913/article/details/118687348
C++ STL array 容器(深入了解,一文学会)                        https://blog.csdn.net/qq_37529913/article/details/118688364
C++ STL pair 类模板(深入了解,一文学会)                       https://blog.csdn.net/qq_37529913/article/details/118714852
C++ STL map容器(深入了解,一文学会)                           https://blog.csdn.net/qq_37529913/article/details/118741670
C++ STL map emplace()和emplace_hint()(深入了解,一文学会)         https://blog.csdn.net/qq_37529913/article/details/118771777
C++ STL multimap容器(深入了解,一文学会)                    https://blog.csdn.net/qq_37529913/article/details/118773021
C++ STL Set容器(深入了解,一文学会)                             https://blog.csdn.net/qq_37529913/article/details/118918940
C++ STL multiset容器(深入了解,一文学会)                      https://blog.csdn.net/qq_37529913/article/details/119624779
C++ STL unordered_map容器(深入了解,一文学会)         https://blog.csdn.net/qq_37529913/article/details/119689199
C++ STL unordered_set容器(深入了解,一文学会)           https://blog.csdn.net/qq_37529913/article/details/119709019
C++ STL unordered_multiset容器(深入了解,一文学会)    https://blog.csdn.net/qq_37529913/article/details/119709079
C++ STL stack容器适配器(深入了解,一文学会)        https://blog.csdn.net/qq_37529913/article/details/119723782
C++ STL queue容器适配器(深入了解,一文学会)       https://blog.csdn.net/qq_37529913/article/details/119746246
C++ STL priority_queue容器适配器(深入了解,一文学会)                https://blog.csdn.net/qq_37529913/article/details/119770527
C++ STL reverse_iterator反向迭代器适配器(深入了解,一文学会)   https://blog.csdn.net/qq_37529913/article/details/119814820
C++ STL insert_iterator插入迭代器适配器(深入了解,一文学会)      https://blog.csdn.net/qq_37529913/article/details/119834378
C++ STL stream_iterator流迭代器(深入了解,一文学会)                  https://blog.csdn.net/qq_37529913/article/details/119834429
C++ STL streambuf_iterator流缓冲区迭代器(深入了解,一文学会)        https://blog.csdn.net/qq_37529913/article/details/119850048
C++ STL move_iterator移动迭代器(深入了解,一文学会)                      https://blog.csdn.net/qq_37529913/article/details/119859888
C++ STL advance()函数(深入了解,一文学会)        https://blog.csdn.net/qq_37529913/article/details/120008250
C++ STL distance()函数(深入了解,一文学会)        https://blog.csdn.net/qq_37529913/article/details/120008300
C++ STL iterator迭代器(深入了解,一文学会)         https://blog.csdn.net/qq_37529913/article/details/120008346
C++ STL const_iterator转换为iterator类型迭代器(深入了解,一文学会)        https://blog.csdn.net/qq_37529913/article/details/120008324
C++ STL begin()和end()函数(深入了解,一文学会)        https://blog.csdn.net/qq_37529913/article/details/120008459
C++ STL prev()和next()函数(深入了解,一文学会)         https://blog.csdn.net/qq_37529913/article/details/120008481
 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++ STL array 容器(深入了解,一文学会) 的相关文章

  • SL4 AutoCompleteBox 重复筛选结果问题

    我在 AutoCompleteBox 过滤方面遇到问题 它似乎记住了之前的过滤器 例如 我输入 A 它会返回 1 项 我删除 A 并输入 Z 这应该返回 1 项 问题是它返回 A 过滤器加上 Z 的结果 我删除 Z 并输入 S 这会带回 2
  • 更快的算法来计算有多少数字可以被范围内的特定整数整除

    int a b c d 0 cin gt gt a gt gt b gt gt c for int i a i lt b i if i c 0 d cout lt
  • 检查列表是否包含另一个列表。 C#

    编辑 只是说 ContainsAllItem 中的注释解释得最好 很抱歉问这个问题 我知道以前有人问过这个问题 但我只是不明白 好的 所以我想检查一个列表是否包含另一个列表中的所有项目WITHOUT重叠 以及根据类字符串 名称变量 称为项目
  • 为什么派生类不使用基类的operator=(赋值运算符)?

    以下是实际问题的简化版本 而不是打电话Base operator int 代码似乎生成了一个临时的Derived对象并复制它 既然函数签名似乎完美匹配 为什么不使用基本赋值运算符 这个简化的示例没有显示任何不良影响 但原始代码在析构函数中有
  • 通过单个 GPIO 引脚转储闪存

    我正在使用 Infineon 的 XMC4500 Relax Kit 并尝试通过单个 GPIO 引脚提取固件 我非常天真的想法是通过 GPIO 引脚一次转储一位 然后用逻辑分析仪以某种方式 嗅探 数据 伪代码 while word by w
  • 关闭 XDOCUMENT 的实例

    我收到这个错误 该进程无法访问文件 C test Person xml 因为它是 被另一个进程使用 IOException 未处理 保存文件内容后如何关闭 xml 文件的实例 using System using System Collec
  • 如何将字节块读入结构体

    我有一个需要处理的资源文件 它包含一组文件 首先 资源文件列出了其中包含的所有文件 以及一些其他数据 例如在此结构中 struct FileEntry byte Value1 char Filename 12 byte Value2 byt
  • C 中的模仿函数重写

    具体来说 函数重写能够调用基本重写方法 这有两部分 一个是预编译的库代码 1 另一个是库的用户代码 2 我在这里实现了一个尽可能最小的经典 Person 和 Employee 示例 非常感谢了解 OOP 概念的铁杆 C 开发人员的回应 我正
  • 用 C# 制作 Vista 风格的应用程序

    我正在运行 Windows Vista 并且希望外观看起来像常规 Vista 程序 有没有关于如何构建 Vista 风格应用程序的真正好的教程 文章 我还想学习如何使用本机代码并将其转换为 C 如this http bartdesmet n
  • 线程安全的 C++ 堆栈

    我是 C 新手 正在编写一个多线程应用程序 不同的编写者将对象推入堆栈 读者将它们从堆栈中拉出 或至少将指针推入对象 C 中是否有任何内置结构可以在不添加锁定代码等的情况下处理此问题 如果没有 那么 Boost 库呢 EDIT 你好 感谢您
  • 更改其他页面的主窗口内容

    在 WPF 应用程序的主窗口中 我有一个 Badged 元素 来自材料设计 这是我的代码
  • C# 中处理 SQL 死锁的模式?

    我正在用 C 编写一个访问 SQL Server 2005 数据库的应用程序 该应用程序是数据库密集型的 即使我尝试优化所有访问 设置适当的索引等 我预计迟早会遇到死锁 我知道为什么会发生数据库死锁 但我怀疑我能否在某个时候发布不发生死锁的
  • 如何不在类中实现接口的功能?

    面试时面试官问了我以下问题 但我不知道这个问题的答案是什么 请帮忙 如果我不想 我必须做什么 在我的类中实现一个函数 在接口中声明为 由我班实施 Edited 我正在使用 NET 和 C 如果有人可以提供 C 示例代码示例 那就太好了 Th
  • 如何在 VS Code 中为 CMake 项目设置 C/C++ IntelliSense?

    我正在尝试使用 libTooling 编写一个工具 我对其进行了设置 以便它可以使用 LLVM 文档中的示例进行编译 然而 C C IntelliSense 似乎不适用于 CMake 项目 我的工具位于
  • asp.net c# 防止在从服务器端代码更改索引时触发 selectedindexchanged 事件

    我在同一个 aspx 页面上有两个下拉列表控件
  • 展开路径中具有环境变量的文件名

    最好的扩张方式是什么 MyPath filename txt to home user filename txt or MyPath filename txt to c Documents and settings user filenam
  • 在何处将 CFLAG(例如 -std=gnu99)添加到 (Eclipse CDT) 自动工具项目中

    我有一个简单的 Autotools C 项目 不是 C 其框架是由 Eclipse CDT Juno 为我创建的 CFLAG 通过检查 似乎是 g O2 我希望所有生成的 make 文件也具有 std gnu99附加到 CFLAG 因为我使
  • 通过 cmake 链接作为外部项目包含的 opencv 库[重复]

    这个问题在这里已经有答案了 我对 cmake 比较陌生 经过几天的努力无法弄清楚以下事情 我有一个依赖于 opencv 的项目 它本身就是一个 cmake 项目 我想静态链接 opencv 库 我正在做的是我的项目中有一份 opencv 源
  • 创建带有部分的选项卡式侧边栏 WPF

    我正在尝试创建一个带有部分的选项卡式侧边栏 如 WPF 中的以下内容 我考虑过几种方法 但是有没有更简单 更优雅的方法呢 方法一 列表框 Using a ListBox并将 SelectedItem 绑定到右侧内容控件所绑定的值 为了区分标
  • 将文本从文本文件添加到 PDF 文件[重复]

    这个问题在这里已经有答案了 这是我的代码 using FileStream msReport new FileStream pdfPath FileMode Create step 1 using Document pdfDoc new D

随机推荐

  • 至强服务器性能排行,英特尔至强处理器排名天梯 至强cpu天梯2020排名

    排名 名称 评分 1 Intel Xeon Platinum 8173M 2 00GHz 28 860 2 Intel Xeon Gold 6154 3 00GHz 27 722 3 Intel Xeon Gold 6138 2 00GHz
  • 【研究生】毕业答辩PPT制作和讲述要点(整理)

    引用网址 http blog sciencenet cn blog 53846 232974 html 引言 在QQ群上和研三的点评答辩ppt制作结果 不知不觉 唠叨 了很多 其中 让大家共享一下彼此的ppt文档 取人所长 不想 学生杨涛有
  • React SSR - 写个 Demo 一学就会

    今天写个小 Demo 来从头实现一下 react 的 SSR 帮助理解 SSR 是如何实现的 有什么细节 什么是 SSR SSR 即 Server Side Rendering 服务端渲染 是指将网页内容在服务器端中生成并发送到浏览器的技术
  • BTC-分叉

    分叉 fork 原来由一条链变为了两条链 造成原因 有可能是两个节点差不多同时挖到了一个区块 然后同时发布出去 这时候就会造成临时性的分叉 state fork forking attack deliberate fork 比特币的协议发生
  • 扫码普通二维码跳转微信小程序指定页面(体验服和开发服跳转链接不能动态传参)

    好久不见 时隔多年我又来记录问题来了 记录这次问题的主要原因是减少你我去搜索资源的时间 下面开始讲讲我越到的问题 下面说的是针对小程序体验版或者开发版哈 正式环境不存在这个问题 需求 pc端扫码登录 pc创建一个二维码 用户用微信自带扫码功
  • Python 中 Iterator和Iterable的区别

    Python中 list truple str dict这些都可以被迭代 但他们并不是迭代器 为什么 因为和迭代器相比有一个很大的不同 list truple map dict这些数据的大小是确定的 也就是说有多少事可知的 但迭代器不是 迭
  • STM32CubMX_MQ135检测空气质量

    一 MQ135简介 MQ135是测量空气污染情况常用的一个传感器 具有代表性 价格低 寿命长 敏感度也OK 主要用于测量空气中二氧化碳 氮氧化物 氨气 酒精 苯类等 这几样气体可以说都属于家用空气污染测定中的重要成份 因此用这个传感器刚刚好
  • BOT_SORT复现(Ubuntu20.04)

    论文地址 https arxiv org abs 2206 14651 代码地址 NirAharon BoT SORT BoT SORT Robust Associations Multi Pedestrian Tracking githu
  • tensorflow:使用卷积网络(CNN)实现mnist

    tensorflow1 8 0 python3 6 4 coding utf 8 import tensorflow as tf from tensorflow examples tutorials mnist import input d
  • 【adb 查看手机当前应用的包名,所有应用的包名以及安装位置】

    1 查看是否连接手机 adb devices 2 进入指定的device的shell adb shell 3 查看当前正在运行的APK的包名 adb shell dumpsys window findstr mCurrentFocus 例如
  • BigInteger 与 BigDecimal的区别

    目录 一 BigInteger 二 BigDecimal 一般来说 BigInteger用的不是很多 BigDecimal用的稍微多一点 就比如说JDBC中 如果一个字段的数据库类型是Number 那么 getObject getClass
  • ES6中声明变量的方法(let,const)

    ECMAScript 6 0 以下简称ES6 是JavaScript语言的下一代标准 已经在2015年6月正式发布了 它的目标 是使得JavaScript语言可以用来编写复杂的大型应用程序 成为企业级开发语言 ECMAScript和Java
  • Android版本大于M时动态申请权限的方法

    问题描述 Android应用开发时 若版本大于M 则有些权限需要在运行时用Java代码进行动态获取 解决方案 添加supportv7包 在build gradle app 文件dependencies节点中 添加v7包的依赖 impleme
  • linux java进程_Java+Linux,深入内核源码讲解多线程之进程

    之前写了两篇文章 都是针对Linux这个系统的 为什么 我为什么这么喜欢写这个系统的知识 可能就是为了今天的内容多线程系列 现在多线程不是一个面试重点 啊 那如果你能深入系统内核回答这个知识点 面试官会怎么想 你会不会占据面试的主动权 我不
  • c# mysql 二进制图片_ASP.NET(C#) 实现将图片以二进制保存到数据库中 转

    注意 上传大文件时 会出现错误 原因我现在还不知道 数据库名 mydata 表名 table img 字段 id 自动编号 filename 文本 img OLE 对象 default aspx 无标题页 default aspx cs u
  • 【电路】电容(三)——耦合、退耦电容

    一 耦合电容 什么是耦合 两个或两个以上的电路构成一个网络时 若其中某一电路中电流或电压发生变化 能影响到其他电路也发生类似的变化 这种网络叫做耦合电路 耦合的作用就是把某一电路的能量输送 或转换 到其他的电路中去 1 电源 导线 电阻 电
  • 蓝牙core_v5.2协议-4 L2CAP上

    本章节主要讲述蓝牙host层的协议 针对BLE 主要关注L2CAP GATT ATT SMP GAP这几层 根据spec的章节顺序 我们一次讲解 PART A A LOGICAL LINK CONTROL AND ADAPTATION PR
  • python的time各种用法

    1 time Python的time模块提供了许多用于处理时间的功能 以下是一些常用的time模块的函数及其用法 并附有示例 time 返回当前时间的时间戳 自1970年1月1日00 00 00起的秒数 import time curren
  • 基于深度学习的高分辨率遥感图像目标检测技术目前的研究现状

    参考 基于深度学习的高分辨率遥感图像目标检测技术目前的研究现状 云 社区 腾讯云 目录 一 概述 二 通用目标检测方法 1 类不平衡问题 2 复杂背景 3 目标的尺度变化 4 特殊视角 5 小目标 三 特定目标检测 1 城市 2 机场 3
  • C++ STL array 容器(深入了解,一文学会)

    array 容器是 C 11 标准中新增的序列容器 简单地理解 它就是在 C 普通数组的基础上 添加了一些成员函数和全局函数 在使用上 它比普通数组更安全 且效率并没有因此变差 和其它容器不同 array 容器的大小是固定的 无法动态的扩展