C ++在类中声明char数组的正确方法是什么?

时间:2013-01-13 07:52:59

标签: c++ arrays class char

这是一种伪代码,但它应该清楚我想知道的内容。我在不同的代码中看到了所有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:
};

3 个答案:

答案 0 :(得分:6)

  

C ++在类中声明char数组的正确方法是什么?

都不是。
在C ++中,正确的方法是使用:

std::string buffer;

这正是C ++提供std::string的原因。它让你自由:

  • 明确管理内存,如#1&amp;
  • 覆盖静态分配数组的边界,如#2

请注意,您显示的3个示例并不等效 #1&amp; #2将字符缓冲区的生命周期绑定到对象实例,
虽然#3没有做同样的事情。

请注意,如果你需要一个本地缓冲区(,其大小是固定的)只是为了传递给c风格的api,那么这种用法并不能很好地利用{{{ 1}}并且可能静态分配的字符数组更合适。

如果您的要求与std::string#1相同,那么更好的选择是#2

答案 1 :(得分:2)

第一个变体:从堆中分配字符数组。 IIRC,析构函数中的删除应为delete [] _buffer

第二个变体:字符数组是类的一部分,并且与类一起生存和死亡。可以从堆或堆栈中分配,具体取决于实例化类的方式。

第三种变体:字符数组在堆栈上分配,并在封闭范围(在本例中为Function() - 结束时)释放。

话虽如此,除非你确实需要一个正确理由的字符数组,否则使用std::string要好得多。

答案 2 :(得分:2)

我不相信你想要做的事情有“一种真正的方法”。每种方法都涉及权衡。具体做法是:

方法1)在堆上分配内存。您会受到(轻微)性能损失。但是,内存中类的大小会减少。如果在堆栈上分配类,则会以这种方式浪费更少的堆栈空间。正如其他人所提到的,您需要使用delete []语句。

关于你的注释,sizeof(buffer)返回4,因为buffer是一个char指针。您的平台定义指针为4字节大。它不会报告已分配数组的大小,因为sizeof适用于所描述的类型。 inet_ntop没有填充你的缓冲区,因为你告诉它你的缓冲区只有4个字节大。 inet_ntop只是失败,因为缓冲区很小。

方法2)这将交换方法1的额外堆分配以增加类的大小。

关于注释,缓冲区未初始化或删除,因为C ++处理它。由于您指示编译器为您提供大小为1024字节的char数组,因此它为您提供了一个。您不需要为编译器初始化/清除。此外,sizeof返回1024,因为类型是1024字节的char数组,因此编译器知道这一点并给出数组大小。它不会返回指针的大小,因为你没有要求指针。

方法3)此方法每次调用函数时都会分配缓冲区,并将其放在堆栈中。根据您打算对数据执行的操作,这可能是最佳解决方案,或根本不适用。如果在函数结束后你不需要缓冲区,那么这是一个不错的选择。