具有移动和复制构造函数的类中的C ++代码重复

时间:2017-07-12 22:25:08

标签: c++ class copy-constructor code-duplication move-constructor

例如,一个包含两个构造函数的类,一个采用引用,另一个采用字符串r值引用。

class A {
    public:

    A(std::string&& str) {
        Foo foo(std::move(str));
        //do something with foo. (e.g., use it to initialize some members)
        field = foo.bar();
    }

    A(const std::string& str) {
        Foo foo(str);
        //do something with foo. (e.g., use it to initialize some members)
        field = foo.bar();
    }

};

如果这两个构造函数除了在移动构造函数中出现的std :: move之外几乎执行相同的操作,有没有办法避免使用两个几乎相同的代码块?

4 个答案:

答案 0 :(得分:2)

按价值接受。这样做可以做到两者都做同样的事情。

答案 1 :(得分:1)

明显的答案:制作第三个fn,它执行公共部分,从其他fns调用。

您可以直接从另一个中调用一个,但这取决于类中存储的数据的性质以及引用的内容。但是,在许多情况下,如果需要,可以使用复制构造函数来实现移动,但效率不高。

答案 2 :(得分:1)

您可以使用通用引用来完成此操作,但仅限于构造函数是模板化的情况。

class A {
public:
    template<typename T>
    A(T && str) {
        Foo foo(std::forward<T>(str));
        //do something
    }
};

答案 3 :(得分:1)

第一个选项是使用模板化构造函数:

class A
{
public:
    template<typename T, typename = std::enable_if<std::is_same<std::remove_reference<T>::type, std::string>::value>::type>
    A(T && str) {
         Foo foo(std::forward<T>(str));
        //do something
    }
};

但它看起来有点难看。如果Foo(const std::string &)实际上复制了字符串,那么我更愿意按值传递参数:

class A
{
public:
    A(std::string str) {
         Foo foo(std::move(str));
        //do something
    }
};

这种方法的开销是额外的移动构造函数。 但不要为此烦恼,因为编译器可能会优化它。