在类的函数中创建字符串时出错
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
数组,因此,您需要将正确的指针指向 first
和 last
,如下所示:
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 时出错