setter 中的 C++ 字符串操作

c++ string manipulation in setter

我可以在 setter 中操作字符串吗?例如,我想将它的长度设置为 20。这可能吗?这是最佳实践吗?我得到 "Non const function is called on const object"。尝试过的代码:

void setName(const string &name) {
    if (name.size() > 20)
    {
        name.reserve(20);
    }
    Employee::name = name;
}

不,在你的例子中 name 是一个 const string 引用所以你只能在它上面使用 const 方法(基本上意味着你不能修改 name) . reserve 不是 const 方法。 const string& name 表示 name 与调用者提供的 相同 字符串,const 表示您不能修改它。

然而,您可以做的是以某种方式创建 name 的副本。最明显的方法可能是在方法内部创建一个副本,这意味着您可以保留函数签名(恕我直言,这可能是一件好事):

void setName(const string &name) {
    string tname = name;
    if (tname.size() > 20)
    {
        tname.reserve(20);
    }
    Employee::name = tname;
}

另一种方法是按值传递 name ,这意味着参数将是调用者提供的内容的副本(有人可能会争辩说不应该改变的签名体现实现的方法,但见仁见智):

void setName(string name) { // note no ampersand

不能/不应该做的是只删除const,因为那意味着参数是与调用者提供的 same 字符串。如果调用者不提供可变名称,它将无法编译,如果提供可变名称,调用者副本也会更改(因为它是相同的)。

您不能改变 const 引用:这意味着您将无法调用 std::string::reserve,因为它不符合 const 条件。

考虑按值取 name

void setName(string name) 
 {
    if (name.size() > 20)
    {
        name.reserve(20);
    }

    Employee::name = name;
}

在这种情况下,将制作传递给 setName 的字符串的副本,可以对其进行变异,保持原始不变。

在我看来,您解决问题的方式是错误的。 当传递的字符串的大小大于 20 时,发布的代码调用 reserve,但这是一个 non-binding 收缩字符串的请求(这是常量,顺便说一句)。

如果要在 setter 中传递常量引用时将 class 的字符串成员限制为特定大小,您所要做的就是仅向其中复制一个子字符串传递的字符串。

I get "Non const function is called on const object"

当然可以。这就是 const 整点 首先!

if (name.size() > 20)
{
    name.reserve(20);
}

这根本没有意义。它的字面意思是:"If the string has more than 20 characters, then make sure that it can internally hold at least 20 characters".

现在,调用 可能 也会使字符串的内部容量缩小到它向外界表示的大于 20 的任何大小。例如,如果您的字符串大小为 30,而其当前容量为 1000,则 reserve(20) 可以 将容量缩减为 30。

但是,这是一个 low-level memory-management 初学者通常不会或不应该关心的问题。如果,我相信,你的意图只是 剪切 字符串,那么你需要 resize.

我会像这样解决你的问题,简单明了:

void setName(std::string const& name)
{
    this->name = name;
    if (this->name.size() > 20)
    {
        this->name.resize(20);
    }
}