【问题标题】:Error when creating a string in a function of class在类的函数中创建字符串时出错
【发布时间】:2016-11-30 12:55:45
【问题描述】:

我创建了一个名为Employee 的类,私下我有一个Name 作为string。这是我的班级声明:

class Employee
{
     string Name;
 public:
     Employee();
     void SetName(string);
     void StringToEmployee(string);
     ~Employee();
 }

这是StringToEmployee(string)方法的定义:

void Employee::StringToEmployee(string s)
{
     char  *first = s, *end = s+strlen(s), *last = NULL;
     last = find(first, end, ',');
     string temp(first, last- first);
     SetName(temp);
}

当我调试到string temp(first, last- first) 行时发生错误,编译器似乎不允许我在方法中构造新字符串。因为我也变成了string temp;,然后是temp.assign(first, last-first)。错误仍然存​​在。如何在方法中创建新字符串?

【问题讨论】:

  • std::strlen 函数是一个 C 函数。它需要一个 C 以 null 结尾的字节字符串作为输入。 IE。指向char 的指针。尝试改用std::string functions
  • 你到底把string 定义为什么? MCVE 的其余部分在哪里?而且,什么是错误的?

标签: c++ string class


【解决方案1】:

您应该使用迭代器并利用标准库的功能,而不是原始指针和 C 风格的字符串函数。这不仅会让您的 C++ 代码更惯用且更易于理解,而且还会隐式解决您的许多错误。

首先,StringToEmployee的实现应该改写如下:

void Employee::StringToEmployee(std::string s)
{
    const std::string temp(s.begin(),
                           std::find(s.begin(), s.end(), ',');
    SetName(temp);
}

但是由于您没有修改s 参数并且不需要它的副本,因此您应该通过常量引用来传递它:

void Employee::StringToEmployee(const std::string& s)
{
    const std::string temp(s.begin(),
                           std::find(s.begin(), s.end(), ',');
    SetName(temp);
}

此外,您应该考虑重新设计您的 Employee 类。目前,您有一个创建无效Employee 对象的默认构造函数,然后您有成员函数允许您通过设置其成员将该无效Employee 对象转换为有效对象。相反,您可以有一个构造函数,一步完成所有这些初始化。您的代码不仅会更简洁、更易于理解,而且效率也会更高!

可能是这样的:

class Employee
{
     std::string Name;                          // name of this employee

 public:
     Employee(const std::string& name);         // create Employee with specified name
     void SetName(const std::string& newName);  // change this employee's name
     ~Employee();
 };



Employee::Employee(const std::string& name)
    : Name(s.begin(), std::find(s.begin(), s.end(), ','))
{ }

void Employee::SetName(const std::string& newName)
{
    Name = std::string(s.begin(), std::find(s.begin(), s.end(), ','));
}

Employee::~Employee()
{ }

几个快速说明:

  • 您会看到,每当我使用标准库命名空间中的类时,我总是明确地写出std::。这是一个非常好的习惯,而且输入额外的 5 个字符并不难。这一点特别重要,因为using namespace std;a really bad habit to get into
  • 我通过常量引用传递不需要修改或在方法内部拥有副本的对象(如字符串)。这既更容易推理,也可能更有效(因为它避免了不必要的复制)。
  • 在构造函数内部,我使用了一种看起来很有趣的语法,包括一个冒号和一些括号。这称为member initialization list,您应该习惯于看到它。这是类的构造函数初始化其成员变量的标准方式。

【讨论】:

    【解决方案2】:

    出于某种原因,您想将std::string 分配给char*。 从您的其他代码来看,您想使用原始 char 数组,因此,您需要将正确的指针指向 firstlast,如下所示:

    char *first = &s[0], *end = (&s[0]) + strlen(s.c_str()), *last = NULL;
    

    这部分:

    string temp(first, last- first);
    

    不正确,因为 last - first 是指针,并且据我所知,您想使用 std::string(const char*, size_t) 构造函数。但是,相反,您使用的是基于迭代器的构造函数,并且系统正确地死了,因为第一个指针大于第二个指针。

    如您所见,您的方法容易出错。我建议使用迭代器重新执行这部分代码,如下所示:

    void Employee::StringToEmployee(string s)
    {
        auto found = find(s.begin(), s.end(), ',');
        string temp(s.begin(), found);
        SetName(temp);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-07-03
      • 1970-01-01
      • 2013-05-27
      • 1970-01-01
      • 2015-06-12
      • 2014-06-13
      • 1970-01-01
      相关资源
      最近更新 更多