繁体   English   中英

有效地初始化const std :: vector类成员

[英]Initialise const std::vector Class Members Efficiently

假设我正在尝试创建“不可变的”类对象(即,成员变量使用const定义)。 因此,当调用构造函数时,我当前调用单独的init函数来初始化类成员。 但结果似乎出现了许多新的矢量创建和矢量复制过程。

如果成员不是const ,则可以在构造函数的{ }部分中执行初始化,然后直接写入values (我认为这样会更有效)。 但这是不可能的。

有没有更好/更干净/更有效的方法来设计不可变类的构造?

#include <vector>

class Data
{
public:
    const std::vector<int> values;

    Data(unsigned int size, int other) : values(init(size, other)) { }
    Data(const std::vector<int>& other) : values(init(other)) { }

private:
    std::vector<int> init(unsigned int size, int other) {
        std::vector<int> myVector(size);

        for (unsigned int i = 0; i < size; ++i)
            myVector[i] = other * i;

        return myVector;
    }

    std::vector<int> init(const std::vector<int>& other) {
        std::vector<int> myVector(other);

        for (unsigned int i = 0; i < other.size(); ++i)
            myVector[i] *= myVector[i] - 1;

        return myVector;
    }
};

int main() {
    Data myData1(5, 3);         // gives {0, 3, 6, 9, 12}
    Data myData2({2, 5, 9});    // gives {2, 20, 72}

    return 0;
}

您当前的设计非常好。 初始化发生在构造函数的成员初始化列表中,因此它将在最坏的情况下触发移动(无论如何对于矢量来说都是很便宜的), 在最佳状态下触发NRVO

NRVO称为返回值优化 当函数返回具有自动存储持续时间的命名变量时,允许编译器取消复制/移动。 但是请注意,即使在省略的情况下,复制/移动构造函数仍然需要可用。 这是一个概括这个概念的虚拟示例:

SomeType foo() { // Return by value, no ref
    SomeType some_var = ...; // some_var is a named variable
                             // with automatic storage duration
    do_stuff_with(var);
    return some_var; // NRVO can happen
}

(您的init函数遵循该模式。)

在C ++ 17中,根据init函数的形状,您甚至可以从这种情况下受益于保证的复制省略。 您可以在其他SO答案中找到有关此内容的更多信息。

注意:由于您已标记问题我认为移动语义可用。

你说

似乎有很多新的向量创建和向量复制正在进行中。

但是我不确定。 相反,我希望在这里进行一次完整的创建和一次移动: init生成并返回一个临时向量(确定完整的向量创建,直接使用最终大小),该向量用于初始化const成员(可以在此处进行一次移动)。 我们应该在这里控制生成的程序集,但是一个不错的编译器应该一次构建数据块,然后将其移入数据成员。

因此,除非您可以通过概要分析(或通过查看编译器生成的程序集)证明确实需要在此处进行优化,否则我将很高兴继续使用此代码,因为它清楚地声明了成员常量。

这里的解决方案是从成员向量中删除const ,以便您可以就地执行初始化,而不是通过复制进行初始化。

如果您希望该values对类的用户可读但不可写,则可以公开对其的const引用:

class Data {
    std::vector<int> values_;

    // constructors...

public:
    std::vector<int> const& values() const { return values_; }
};

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM