gpt4 book ai didi

c++ - 使用字符串成员构造对象的有效方法

转载 作者:行者123 更新时间:2023-11-28 01:21:46 25 4
gpt4 key购买 nike

假设我有一个类 ThisHasAStringMember。假设它有一个私有(private)成员,它是一个字符串,我想有效地获取字符串值,在可能的情况下更喜欢 move 而不是拷贝。以下两个构造函数可以做到这一点吗?

class ThisHasAStringMember
{
public:
// ctors
ThisHasAStringMember(const std::string str) : m_str(str) {}
ThisHasAStringMember(std::string &&str) : m_str(std::move(str)) {}

// getter (no setter)
std::string value() { return m_str; }
private:
std::string m_str;
}

我是否需要在第二个构造函数中的 str 参数之前使用双符号?

这是完成此任务的正确方法吗?

最佳答案

起初我会注意到最好将构造函数标记为显式。

下一步是最好更改解决方案中的第一个构造函数以采用 const 引用以避免复制左值:

// ctors
ThisHasAStringMember(const std::string& str) : m_str(str) {}
ThisHasAStringMember(std::string &&str) : m_str(std::move(str)) {}

从性能的角度来看,这种方法是最佳的(您将有一个复制构造函数调用左值和一个 move 构造函数调用右值),但是在这种情况下每次实现两个构造函数是很无聊的。如果您有 N 个成员 - 2^N 个构造函数。

有几个选择:

  1. Signle 构造函数,您可以在其中仅按值传递参数。是的,它在 C++98 中效率低下,但在 C++11 中,当您创建完整拷贝时 - 这是一个选项。

    ThisHasAStringMember(std::string str) : m_str(std::move(str)) {}

传递左值时,将调用一次复制构造函数和一次 move 构造函数。当传递右值时,将有两个 move 构造函数调用。是的,在每种情况下,您都有一个额外的 move 构造函数调用。但它通常非常便宜(甚至可以被编译器优化掉)并且代码非常简单。

  1. 通过右值传递参数的单个构造函数:

    ThisHasAStringMember(std::string&& str) : m_str(std::move(str)) {}

如果你传递左值,你必须首先在调用的地方明确地复制它,例如ThisHasAStringMember(复制(someStringVar))。 (这里的copy是一种简单的模板复制方式)。而且你仍然会有一个额外的 move 构造函数调用左值。对于右值,不会有开销。我个人喜欢这种方法:复制参数的所有位置都是显式的,您不会在性能关键的地方偶尔进行复制。

  1. 制作构造函数模板并使用完美转发:
template <typename String, 
std::enable_if_t<std::is_constructible_v<std::string, String>>* = nullptr>
ThisHasAStringMember(String&& str) : m_str(std::forward<String>(str))
{}

右值和左值都没有开销,但在大多数情况下,您需要制作构造函数模板并在 header 中定义它。

关于c++ - 使用字符串成员构造对象的有效方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55873908/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com