在类的函数中创建字符串时出错

Posted

技术标签:

【中文标题】在类的函数中创建字符串时出错【英文标题】: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 的其余部分在哪里?而且,什么是错误的? 【参考方案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);

【讨论】:

以上是关于在类的函数中创建字符串时出错的主要内容,如果未能解决你的问题,请参考以下文章

在类路径资源 + Springboot 中创建名称为“dataSource”的 bean 时出错

在 Spring 框架中创建名称在类路径资源 [application-context.xml] 中定义的 bean 时出错

在类中创建对象

在 C# Monodevelop 中创建 Uri 时出错

在类的构造函数上使用受保护的访问修饰符

如何在模板化类的私有部分中创建模板化结构