How can I initialize char arrays in a constructor?

2019-04-20 21:33发布

问题:

I'm having trouble declaring and initializing a char array. It always displays random characters. I created a smaller bit of code to show what I'm trying in my larger program:

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();
}

And sorry if my formatting is bad, I can barely figure out this website let alone how to fix my code :(

回答1:

If there are no particular reasons to not use std::string, do use std::string.

But if you really need to initialize that character array member, then:

#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();
}


回答2:

Your constructor is not setting the member variable name, it's declaring a local variable. Once the local variable goes out of scope at the end of the constructor, it disappears. Meanwhile the member variable still isn't initialized and is filled with random garbage.

If you're going to use old-fashioned character arrays you'll also need to use an old-fashioned function like strcpy to copy into the member variable. If all you want to do is set it to an empty string you can initialize it with name[0] = 0.



回答3:

Considering you tagged the question as C++, you should use 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")
{

}


回答4:

Since you are using C++, I suggest using strings instead of char arrays. Otherwise you'd need to employ strcpy (or friends).

Also, you forgot to delete the test1 instance.

#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;
}


回答5:

c++11 actually provides two ways of doing this. You can default the member on it's declaration line or you can use the constructor initialization list.

Example of declaration line initialization:

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

Example of constructor initialization:

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

You can see a live example of both of these here: http://ideone.com/zC8We9

My personal preference is to use the declaration line initialization because:

  1. Where no other variables must be constructed this allows the generated default constructor to be used
  2. Where multiple constructors are required this allows the variable to be initialized in only one place rather than in all the constructor initialization lists

Having said all this, using a char[] may be considered damaging as the generated default assignment operator, and copy/move constructors won't work. This can be solved by:

  1. Making the member const
  2. Using a char* (this won't work if the member will hold anything but a literal string)
  3. In the general case std::string should be preferred


标签: c++ arrays char