【发布时间】:2018-06-27 14:03:38
【问题描述】:
以下是我的典型代码示例。 A 有很多看起来像这样的对象:
struct Config
{
Config();
Config(const std::string& cType, const std::string& nType); //additional variables omitted
Config(Config&&) = default;
Config& operator=(Config&&) = default;
bool operator==(const Config& c) const;
bool operator!=(const Config& c) const;
void doSomething(const std::string& str);
bool doAnotherThing(const MyOtherObject& obj);
void doYetAnotherThing(int value1, unsigned long value2, const std::string& value3, MyEnums::Seasons value4, const std::vector<MySecondObject>& value5);
std::string m_controllerType;
std::string m_networkType;
//...
};
//...
Config::Config(const std::string& cType, const std::string& nType) :
m_controllerType(cType),
m_networkType(nType)
{
}
我的动机和对该主题的一般理解:
- 在构造函数和方法中使用 const 引用以避免在传递对象时重复复制。
- 简单类型 - 按值传递;类和结构 - 通过 const 引用(或当我需要修改它们时的简单引用)传递
- 强制编译器创建
default移动构造函数和移动赋值,这样它就能够完成它的神奇魔法,同时它可以避免编写无聊的ctor() : m_v1(std::move(v1)), m_v2(std::move(v2)), m_v3(std::move(v3)) {}。 - 如果表现不佳,请使用 libc 和原始指针,然后将其包装在课堂上并写注释。
我有一种强烈的感觉,即根据经验法则是有缺陷的,而且根本不正确。
看完cppreference、Scott Mayers、C++标准、Stroustrup等,我的感觉是:“是的,这里的每一个字我都懂,但还是没有任何意义”。我唯一能理解的就是当我的类包含不可复制的类型(如 std::mutex 和 std::unique_ptr)时,移动语义是有意义的。
我见过很多代码,人们通过值传递复杂的对象,比如大字符串、向量和自定义类——我相信这就是移动语义发生的地方,但是,再次,你如何将对象传递给函数通过移动?如果我是正确的,它会使对象处于“某种空状态”,使其无法使用。
所以,问题是:
- 我如何正确地决定传递值和传递引用?
- 我是否需要同时提供复制和移动构造函数?
- 我需要显式编写移动和复制构造函数吗?我可以使用= default 吗?我的类主要是 POD 对象,因此不涉及复杂的登录。
- 调试时,我总是可以在我自己的类的构造函数中写std::cout << "move\n"; 或std::cout << "copy\n";,但是我怎么知道stdlib 中的类会发生什么?
附:它可能看起来像是绝望的呐喊(确实如此),而不是一个有效的 SO 问题。我根本不知道如何比这更好地表述我的问题。
【问题讨论】:
标签: c++ c++11 move move-semantics stdmove