简体   繁体   English

将 const char[] 初始化为非静态 class 成员

[英]initialize const char[] as non-static class member

class foo {
  public:
    const char name[100];

    foo(const char name[]) : name(name) {};
};

int main(){
  foo("test");

  return 0;
}

Does not compile.不编译。 How do I initialize const char[] non-static class member?如何初始化const char[]非静态 class 成员?

You have different option, depending on what you want to achieve.您有不同的选择,具体取决于您想要实现的目标。

arrays in C++ are strange beasts, they do not behave like most other types, in particular they decay to pointers and do not have copy-constructors (unless wrapped in a structure/class). C++ 中的 arrays 是奇怪的野兽,它们的行为不像大多数其他类型,特别是它们衰减为指针并且没有复制构造函数(除非包装在结构/类中)。

foo(const char name[]) does not take an array by value/by copy, it takes a pointer (yes, the syntax is confusing). foo(const char name[])不按值/按副本获取数组,它需要一个指针(是的,语法令人困惑)。

Thus name(name) is trying to initialize an array with a pointer.因此name(name)试图用指针初始化一个数组。 If this would compile, it would make it super-easy to overflow the stack by accident, as there is no guarantee that the pointer name points to an array that is long at most 100 elements.如果这样可以编译,那么意外溢出堆栈将变得非常容易,因为不能保证指针名称指向的数组最多包含 100 个元素。

Solution 1解决方案 1

Use a more suitable construct - use a string.使用更合适的构造 - 使用字符串。

From your snippet, it seems you want to store a piece of text (variable named name , initialisation with a string-literal...), so a std::string or other string-like class (even const char* ) is a better construct.从您的代码段中,您似乎想要存储一段文本(变量名为name ,使用字符串文字进行初始化...),因此 std::string 或其他类似字符串的 class (甚至const char* )是更好的构造。

class foo {
  public:
    std::string name;

    explicit foo(std::string name_) : name(name_) {};
};
    
    int main(){
      foo("test");
    }

Solution 2解决方案 2

Use a better array使用更好的数组

If you really need to store/copy an array, consider using std::array (since c++11)如果您确实需要存储/复制数组,请考虑使用std::array (c++11 起)

#include <array>

class foo {
   public:
     std::array<char, 100> name;

    explicit foo(std::array<char, 100> name_) : name(name_) {};
};

int main(){
    foo(std::array<char, 100>{"test"});
}

Solution 3解决方案 3

Pass the array by const-ref.通过 const-ref 传递数组。

There are use--cases where you really want to use an array.在某些用例中,您确实想使用数组。 In this case you need to pass the value by reference, and copy the content with std::initializer_list (since c++14, but it's possible to emulate in c++11)在这种情况下,您需要通过引用传递值,并使用 std::initializer_list 复制内容(自 c++14 起,但可以在 c++11 中进行模拟)

#include <utility>
    
class foo {
  template <std::size_t... PACK1>
  explicit foo(const char (&name_)[100], std::index_sequence<PACK1...>)
    : name{ name_[PACK1]... }
  {}

  const char name[100];

  public:
  explicit foo(const char (&name_)[100])
    : foo(name_, std::make_index_sequence<100>{})
  {}
    
};
    
    int main(){
        const char hello[100] = "hello!";
        foo f = foo(hello);
    }

const char (&arr)[100] is an array of length 100 passed by const-reference. const char (&arr)[100]是一个由 const-reference 传递的长度为 100 的数组。 As arrays do not have copy-constructors, we need to use index_sequence to initilize all members.由于 arrays 没有复制构造函数,我们需要使用index_sequence来初始化所有成员。

Solution 4解决方案 4

Use pointers and initialize the array in 2 phases.使用指针并分两个阶段初始化数组。

Passing the array by const-reference means you need to create such a big array beforehand, and that you cannot pass a string literal which length is not exactly 101 (because of terminatig \0 ).通过 const-reference 传递数组意味着您需要事先创建一个如此大的数组,并且您不能传递长度不完全为 101 的字符串文字(因为 terminatig \0 )。

#include <cstring>
    
class foo {
  const char name[100];
public:
  // constructor requires copy... unsure if needs to be so
  explicit foo(const char* name_)
  {
      std::copy(name_, name_ + std::strlen(name_), name);
  }
};
    
int main(){
    const char test[100] = "test!";
    foo f = foo(test);
}

i would sugest to use a std::string if you are using c++, but if the const char [] is a must, here is the solution, basically you just copy some portion of the shortest string to the array of size 100 , leaving unfilled the extra space(ie: name will result in name = ['t','e','s','t','\0',...] https://www.cplusplus.com/reference/cstring/memcpy/如果您使用的是 c++,我建议使用std::string ,但如果const char []是必须的,这里是解决方案,基本上您只需将最短字符串的一部分复制到大小为100的数组中,留下未填充多余的空格(即: name将导致name = ['t','e','s','t','\0',...] https://www.cplusplus.com/reference /cstring/memcpy/

https://ideone.com/91nC60 https://ideone.com/91nC60

 #include <iostream>
    class foo{
        const char *name;
    public:
        void showme(){
            std::cout<<name<<std::endl;
        };
        foo(const char *_name) : name(_name) {
    
        };
    };
    
    int main(){
      foo a("test");
      a.showme();
      return 0;
    }

or或者

#include <iostream>
struct foo{
    const char *name;
    void showme(){
        std::cout<<name<<std::endl;
    };
};

int main(){
    foo a={
        .name="test"
    };
    a.showme();
    return 0;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM