如何在构造函数中初始化字符数组?

11

我在声明和初始化char数组时遇到了问题。它总是显示随机字符。我创建了一个较小的代码段来展示我在我的大型程序中所尝试的内容:

class test
{
    private:
        char name[40];
        int x;
    public:
        test();
        void display()
        {
            std::cout<<name<<std::endl;
            std::cin>>x;
        }
};
test::test()
{
    char name [] = "Standard";
}

int main()
{   test *test1 = new test;
    test1->display();
}

如果我的格式不好,请原谅,我几乎弄不清楚这个网站,更不用说如何修复我的代码了 :(


好的,现在我正在使用std::string,但是在我所编写的较大程序中,我使用了以下这样的get函数:void get(char prompt[], int size,char b[]),其中char b[]是我之前使用的字符数组。为了将字符串传递给我的get函数,我该如何修改它? - ShengLong916
返回一个 std::string 对象,而不是 void - ildjarn
5个回答

10
如果没有特殊原因不使用std::string,请使用std::string。但如果你确实需要初始化字符数组成员,则:
#include <assert.h>
#include <iostream>
#include <string.h>
using namespace std;

class test
{
    private:
        char name[40];
        int x;
    public:
        test();
        void display() const
        {
            std::cout<<name<<std::endl;
        }
};

test::test()
{
    static char const nameData[] = "Standard";

    assert( strlen( nameData ) < sizeof( name ) );
    strcpy( name, nameData );
}

int main()
{
    test().display();
}

1
我认为main函数体有点晦涩,需要考虑到提问者的学习阶段 :) - sehe
所以我决定使用std::string,但是根据我上面的评论,我该如何将一个字符串传递到另一个函数中? - ShengLong916

6
您的构造函数没有设置成员变量“name”,而是声明了一个局部变量。一旦局部变量在构造函数结束时超出范围,它就会消失。同时,成员变量仍未初始化,并且被填充了随机垃圾。
如果您要使用老式字符数组,也需要使用像“strcpy”这样的老式函数将其复制到成员变量中。如果您只想将其设置为空字符串,则可以使用“name [0] = 0”进行初始化。

5

由于您正在使用C ++,建议使用字符串而不是字符数组。否则,您需要使用strcpy(或类似函数)。

另外,您忘记删除test1实例了。

#include <iostream>
#include <string>

class test
{
    private:
        std::string name;
        int x;
    public:
        test();
        void display()
        {
            std::cout<<name<<std::endl;
        }
};

test::test()
{
    name = "Standard";
}

int main()
{   
    test test1;
    test1.display();

    std::cin>>x;
}

1
字符数组的使用场景:C++ 可以在标准库不可用的地方使用,例如微控制器。 - ABCD.ca

5

考虑到您将问题标记为 C++,您应该使用 std::string:


#include <string>

class test
{
    private:
        std::string name;
        int x;
    public:
        test();
        void display()
        {
            std::cout<<name<<std::endl;
            std::cin>>x;
        }
};
test::test() : name("Standard")
{

}

1
我从来没有完全理解为什么稍后发布的“相同”的答案会获得更多的赞。而且我的答案从一开始就可以说是(相当)更完整的... - sehe
我还不太了解这个网站,我尝试给两个都点赞,但是没成功。抱歉。 - ShengLong916
@user1371155 没关系,我并没有真正责怪任何人 :) - sehe
@sehe:为了不偏袒第一个答案,并希望给其他答案更多的曝光率,得分相同的答案会随机排序。这意味着不是第一个发布的答案获得更多的曝光率,而是第一个获得赞同的答案;这可能更好,但差别不大。 - Matthieu M.

3

实际上提供了两种方法来完成这个操作。你可以在声明行上默认成员,也可以使用构造函数初始化列表。

声明行初始化的示例:

class test1 {
    char name[40] = "Standard";
public:
    void display() { cout << name << endl; }
};

构造函数初始化的示例:
class test2 {
    char name[40];
public:
    test2() : name("Standard") {};
    void display() { cout << name << endl; }
};

您可以在此处查看这两个示例的实时演示:http://ideone.com/zC8We9

我个人更喜欢使用声明行初始化,因为:

  1. 当不需要构造其他变量时,这允许使用生成的默认构造函数
  2. 当需要多个构造函数时,这允许在一个地方初始化变量,而不是在所有构造函数初始化列表中都进行初始化

说了这么多,使用char[]可能被认为是有害的,因为生成的默认赋值运算符和复制/移动构造函数将无法工作。解决方法如下:

  1. 使成员变量const
  2. 使用char*(如果成员变量除了字面字符串以外还会持有其他内容,则此方法行不通)
  3. 在一般情况下,应优先考虑使用std::string

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接