在类中声明字符数组的正确方法是什么?
C++ What is the right way of declaring a char array in a class?
这是一种伪代码,但它应该清楚地表明我想知道什么。我在不同的代码中看到了所有3个变体。
我的问题是哪一种是正确的方法,为什么?(参见代码片段中的注释)
test.h第一种方式:
class Test {
public:
Test()
:_buffer(NULL)
{
_buffer = new char[1024];
}
~Test() {
delete _buffer;
}
int Function() {
//use some function like inet_ntop doesn't work _buffer is not filled
inet_ntop(p->ai_family, addr, _buffer, sizeof(_buffer)-1);
//here sizeof(_buffer) returns 4, WHY ?
cout << sizeof(_buffer) << endl;
}
private:
char *_buffer;
};
test.h第二种方式:
class Test {
public:
Test() {
//_buffer is never initialized WHY ?
}
~Test() {
//_buffer is never deleted WHY ?
}
int Function() {
//use some function like inet_ntop works correctly here _buffer is filled
inet_ntop(p->ai_family, addr, _buffer, sizeof(_buffer)-1);
//here sizeof(_buffer) returns 1024, WHY ?
cout << sizeof(_buffer) << endl;
}
private:
char _buffer[1024];
};
test.h第三种方式:
class Test {
public:
Test() {
}
~Test() {
}
int Function() {
char buffer[1024];
//use some function like inet_ntop works correctly here _buffer is filled
inet_ntop(p->ai_family, addr, _buffer, sizeof(_buffer)-1);
//here sizeof(_buffer) returns 1024
cout << sizeof(_buffer) << endl;
}
private:
};
c++在类中声明char数组的正确方法是什么?
。
在c++中,正确的方法是使用:
std::string buffer;
这正是c++提供std::string
的原因。它给你自由从:
- 显式管理内存,如
#1
& - 覆盖
#2
中静态分配数组的边界。
请注意,您所展示的3个示例是不相等的。#1
,#2
将字符缓冲区的生命周期绑定到对象实例,
而#3
则不这样做。
注意,如果你需要一个本地缓冲区(谁的大小是固定的)只是为了传递给一个c风格的api,那么这种用法不能很好地利用std::string
提供的好处,可能一个静态分配的字符数组更合适。
如果您的要求与#1
和#2
一样,那么更好的选择当然是std::string
。
第一个变量:从堆中分配字符数组。在IIRC中,析构函数中的delete应该是delete [] _buffer
。
第二个变体:字符数组是类的一部分,随类而生,随类而死。可以从堆或堆栈中分配,具体取决于类的实例化方式。
第三种变体:字符数组在堆栈上分配,并在封闭作用域(本例中为Function()
)结束时释放。
话虽如此,除非您出于正当理由确实需要一个字符数组,否则使用std::string
要好得多。
我不相信你想要做的事情有"唯一正确的方法"。每种方法都需要权衡利弊。具体来说:
方法1)在堆上分配内存。您将遭受(轻微的)性能损失。但是,类在内存中的大小减少了。如果在堆栈上分配类,这样可以减少浪费的堆栈空间。正如其他人所提到的,您需要使用delete []
语句。
关于你的评论,sizeof(buffer)返回4,因为buffer是一个char指针。您的平台将指针定义为4字节大。它不报告分配的数组的大小,因为sizeof对描述给它的类型起作用。Inet_ntop不会填满你的缓冲区,因为你告诉它你的缓冲区只有4字节大。Inet_ntop只是失败,因为缓冲区太小了。
方法2)用方法1的额外堆分配换取增加的类大小。
对于注释,缓冲区不会被初始化或删除,因为c++会处理这些。由于您指示编译器为您提供一个大小为1024字节的字符数组,因此它为您提供了一个。您不需要为编译器初始化/清理。同样,sizeof返回1024,因为类型是1024字节的char数组,因此编译器知道这一点并给出数组大小。它不会返回指针的大小因为你没有要求指针
Method 3)此方法在每次调用函数时分配缓冲区,并将其放在堆栈上。根据您打算如何处理数据,这可能是最好的解决方案,也可能根本不适用。如果在函数结束后不需要缓冲区,那么它是一个不错的选择。
- 为不同配置设置MSVC_RUNTIME_LIBRARY的正确方法是什么
- 在C++中,将大的无符号浮点数四舍五入为整数的最佳方法是什么
- 实现无开销push_back的最佳方法是什么
- C++从另一个类访问公共静态向量的正确方法是什么
- 在 c++ 中拥有一组结构的正确方法是什么?
- 通过JNI传递数据数组的最快方法是什么
- 用常见虚拟函数实现的任意组合来实现派生类的正确方法是什么
- 使用不同的CRT将新的C++代码与旧的(二进制)组件隔离开来的最佳方法是什么
- 当无法使用模板和宏时,生成类型变体C++代码的最简单方法是什么?
- 在另一个类视图中添加最多2个图表的正确方法是什么
- 在C++中样板"冷/never_inline"错误处理技术的最佳方法是什么?
- 在 c++ 中对类中的 c 字符串动态数组进行排序的最佳方法是什么?
- 在C++中包含原型文件的正确方法是什么?
- 在 OpenCV C++ 中估计基本矩阵之前对相应点进行归一化的正确方法是什么?
- 在PostgreSQL中根据它们的ID选择大量行的最快方法是什么?
- 在OSX上使用CMake将Adobe的XMP工具包构建为共享库的最简单方法是什么?
- 将一系列整数放入类的最佳方法是什么?
- 从长整整转换为uint64_t的推荐方法是什么?
- 将此布尔值传递给此函数的最有效方法是什么?
- 通过比较C++中的行在 txt 文件中搜索的最简单方法是什么?