在这种情况下如何从“const char *”类型初始化字段?

时间:2018-06-04 09:30:44

标签: c++ c++11

给定具有字段const char* filename;的类,以便该类的名称例如是MyClass。

#include <cstring>
class MyClass{
const char* filename;
public:
       MyClass(const char* name);
};

如何按filename初始化字段name? 注意:我必须使用strcpy功能执行此操作 有没有办法用初始化列表来做到这一点?

3 个答案:

答案 0 :(得分:4)

  

有没有办法用初始化列表做到这一点?

有,您需要使用strdup功能:

class MyClass {
    const char* filename;
public:
    MyClass(const char* name)
        : filename(strdup(name))
    {
        if(!filename)
            throw std::bad_alloc(); // strdup failed.
    }

    ~MyClass() {
        free(const_cast<char*>(filename));
    }

    MyClass(MyClass const&) = delete;
    MyClass& operator=(MyClass const& b) = delete;
};

答案 1 :(得分:1)

MyClass::MyClass(char const* filename)
    : filename(strcpy(new char[strlen(filename) + 1], filename))
    //                                          ^^^ space for trailing 0!
{ }

使用new时,如果分配失败,将抛出std :: bad_alloc并且永远不会调用strcpy,所以我们没事。

不要忘记析构函数中的delete[] filename;(不是free,你没有malloc!),否则你会有内存泄漏。

编辑 (从Maxim的评论中窃取想法......):

使用lambda,你可以从效率更高的memcpy中获利:

MyClass::MyClass(char const* filename)
    : filename([](char const* value)
      {
          size_t len = strlen(filename) + 1;
          return reinterpret_cast<char*>(memcpy(new char[len], value, len));
      }())
{ }

但是,如果您切换到std::string而不是免费获得所有这些麻烦:

MyClass
{
    std::string filename;
public:
    MyClass(char const* filename) : filename(filename) { }
};

你甚至不需要一个明确的析构函数(假设没有其他东西可以清理......) - 如果需要的话,在filename.c_str() getter中使用char const*

答案 2 :(得分:0)

使用char*非常棘手。我建议你使用字符串来存储filename。但您仍然想使用char*。您可以尝试如下:

MyClass(const char* name)
{
  filename = new char[100];
  for(int i=0;name[i]!='\0';i++) 
  {
     filename[i]=name[i];
  }
}