在类中声明字符数组的正确方法是什么?

C++ What is the right way of declaring a char array in a class?

本文关键字:方法 是什么 数组 声明 字符      更新时间:2023-10-16

这是一种伪代码,但它应该清楚地表明我想知道什么。我在不同的代码中看到了所有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)此方法在每次调用函数时分配缓冲区,并将其放在堆栈上。根据您打算如何处理数据,这可能是最好的解决方案,也可能根本不适用。如果在函数结束后不需要缓冲区,那么它是一个不错的选择。