C++ 手写std
手写 std::array
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#include <iostream>
// 不使用模板定义数组
class MyArray0
{
private:
// int m_Data[];
int *m_Data;
public:
MyArray0(int size)
{
// m_Data = new int[size];
m_Data = (int *)malloc(size);
}
~MyArray0()
{
delete[] m_Data;
}
};
// 使用模板定义数组
template <typename T, size_t S>
class MyArray1
{
private:
T m_Data[S];
public:
// 返回数组大小
constexpr size_t size() const { return S; }
// 重载下标操作符
// T operator[](size_t index) { return m_Data[index]; } // data[0] = 1; error expression must be a modifiable lvalue
T &operator[](size_t index) { return m_Data[index]; } // data[0] = 1; ok
// const T &operator[](size_t index) // data[0] = 1; error expression must be a modifiable lvalueC
// {
// if (index >= S)
// {
// throw std::out_of_range("Index out of range");
// // __debugbreak();
// }
// return m_Data[index];
// }
T *getData() { return m_Data; }
const T *getData() const { return m_Data; }
};
int main(int argc, char const *argv[])
{
// C++标准数组
// int array[5];
// int array[size]; // error: identifier "size" is undefinedC/
// int size = 5;
// int *heapArray = new int[size];
// delete[] heapArray;
// std::array
// std::array<int, 10> stdArray;
// MyArray0 myArray(5); // ok
static_assert(sizeof(MyArray0) == sizeof(int *), "MyArray0 is not zero size!");
MyArray1<int, 5> data;
size_t size = data.size();
// data[0] = 1;
// 设置数组元素为0,不设置的话,数组元素为随机值
memset(data.getData(), 0, data.size() * sizeof(int));
data[1] = 89;
// 打印数组元素
for (size_t i = 0; i < data.size(); i++)
{
std::cout << data[i] << std::endl;
}
return 0;
}
MyArray1
的内存分配情况?
在 MyArray1
类中,m_Data
是一个大小为 S 的数组,作为类的成员变量。该数组是在模板类 MyArray1<T, S>
实例化时分配内存的。内存分配位置取决于你如何使用 MyArray1
的实例。
如果你在函数内部创建了 MyArray1
类的对象,例如:
1
2
3
4
void myFunction() {
MyArray1<int, 5> myArray;
// 这里 myArray 的存储空间以及 m_Data 的内存都被分配在栈上。栈是自动分配并且在函数调用结束后自动释放的内存区域。
}
如果你用 new 在堆上动态创建 MyArray1
的实例,比如:
1
2
3
4
MyArray1<int, 5>* myArray = new MyArray1<int, 5>();
// ...
delete myArray;
// 在这个例子中,myArray 指向的对象以及 m_Data 的内存都被分配在堆上。堆是一个需要程序员手动管理内存的区域,意味着你需要显式地创建和删除对象。
因此,m_Data
的内存是在栈上还是堆上,取决于你如何声明和初始化你的 MyArray1
对象。通常来说,在栈上创建对象比较快和简单,但堆上可以创建更大的对象,并可以跨函数调用持续存在。
手写 std::vector
本文由作者按照 CC BY 4.0 进行授权