为什么将向量视为通过值传递,即使它是由const引用传递的?

时间:2015-10-12 10:56:35

标签: c++ oop c++11 vector reference

我最近编写了一个非常简单的class代码,它负责查找std::vector中的最小值和最大值并发现,即使我将集合作为{{1}传递} const reference'构造函数,然后从外部更改向量(即将元素推入其中或从中移除一个元素),class内的向量保持不变。

class

我认为传递引用的点是为了不复制大对象,但是我的代码现在的工作方式似乎是复制集合。

#include <vector>
#include <algorithm>

class MinMaxFinder
{
public:
    MinMaxFinder(const std::vector<int>& numbers) : numbers(numbers)
    {
    }
    const int Min() const
    {
        this->findMinAndMax();
        return this->min;
    }
    const int Max() const
    {
        this->findMinAndMax();
        return this->max;
    }

protected:
    std::vector<int> numbers;
    int min;
    int max;

    void findMinAndMax()
    {
        // std::minmax_element call to find min and max values
    }
};

#include <vector> #include <iostream> #include "MinMaxFinder.h" int main(int argc, char* argv[]) { std::vector<int> v{ 1, -6, 12, 158, -326 }; MinMaxFinder mmf(v); v.push_back(-9999999); v.push_back(9999999); auto min = mmf.Min(); auto max = mmf.Max(); } 的值为min-326的值为max,即使值158非常清楚比9999999大得多。

我设法通过将私有成员158的定义更改为numbers来解决此问题,但这是正确的解决方案吗?

但是,为什么内部集合的状态仍然没有变化,它是否不会违反常量传递的定义?

4 个答案:

答案 0 :(得分:6)

ApplicationContext应为std::vector<int> numbers;,这样您就可以在不复制对象的情况下引用对象,也可以更改对象。

但严肃的说,这堂课有什么意义?巨大的矫枉过正!只需使用const std::vector<int>& numbers;std::min_elementstd::max_element ..

std::minmax_element

答案 1 :(得分:3)

  

我认为传递引用的点是为了不复制大对象

是的,没错,当&#34;调用&#34;时,不会复制大对象。构造函数。

但是,您的数据成员是值,而不是引用,因此会立即复制参数以初始化成员。

这就像写这个:

std::vector<int> v;
const std::vector<int>& ref = v;
std::vector<int> v2 = ref;

然后想知道为什么v2是副本。 :)

答案 2 :(得分:2)

在构建上调用的成员初始化numbers(numbers)进行深层复制。

如果您要计算构造的最小值和最大值,那么您不需要将numbers保留为类成员。

可以存储引用作为类成员,但是您必须小心将类实例的生命周期限制为向量在范围内,否则引用可以悬挂。我建议不要这样做。

答案 3 :(得分:0)

成员varialbe numbers未声明为引用,因此在初始化时将复制它,即使ctor的参数是通过引用传递的。尝试将声明更改为:

protected:
    const std::vector<int>& numbers;