代码之家  ›  专栏  ›  技术社区  ›  Tryer

为什么通过const函数返回std::vector元素的地址是错误的?

  •  0
  • Tryer  · 技术社区  · 6 年前

    我已经看了下面的线程,但他们没有谈到 const 地址返回函数的性质:

    (1) Returning a pointer to a vector element in c++

    (2) It's safe to return address of a std::map value?

    在代码中:

    class test_c{
        private: 
            std::vector <double> dblvec;
            double *dblarray;
        public:
            double *AddVecElem(int index){return &dblvec[index];} //Fine
            double *AddVecElem(int index) const {return &dblvec[index];} //compiler error "Return value type does not match function type"
            double *AddArrElem(int index){return &dblarray[index];}//Fine
            double *AddArrElem(int index) const {return &dblarray[index];}//Fine
    };
    

    仅当返回向量元素的地址作为 函数生成编译器错误。

    为什么会这样?返回向量元素的地址如何影响对象的状态?

    2 回复  |  直到 6 年前
        1
  •  3
  •   t.niese    6 年前

    因为 dblvec[index] 在一个 const

    const_reference operator[]( size_type pos ) const;
    

    从那时起 &dblarray[index] 属于 const double * ,并且无法将其转换为 double * .

    dblarray[index] double 双倍*

    检查问题 What can a 'const' method change? 有关什么是const的更多详细信息,请参阅const函数。

        2
  •  3
  •   Swordfish    6 年前

    如果将函数声明为class const function,这意味着您不能从函数中更改类的变量,您不能返回类变量的地址,除非您保证此函数返回一个不可更改的(const)值。

    内部 const 函数,该函数将类的变量视为 常数 变量,所以当您尝试返回地址时,实际上返回 const double * double *

    这种情况的解决方案是返回一个指向 const T :

    const double* AddVecElem(int index) const {return &dblvec[index];}
    

    或者,如您所述,将此函数声明为非常量函数。

    另一种解决方案是返回非指针值(值的副本),并使用 void setValue(..) 函数更改此类的变量数据。

    double *dblarray 函数不会返回指针本身,而是返回变量的副本(注意-函数返回 double* 并且变量在同一指针级别内-因此它返回一个副本)。就像下面的例子:

    private:
        int value;
    public:
        int return_value() const {
            return value; // Copy of the const returns - you don't change class's variable data
        }
        int* return_pointer_value() const {
            return &value; // Compiler error - expected int* returns const int*
        }
    

    所以,如果你想让指针的位置等于向量的位置,你应该返回 double** 双倍*

    double **AddArrElem(int index) const {
        return &dblarray; // Compiler error - expected double** returns const double *const*
        // (*const)=> for 'dblarray', (*)=> for '&'
    }
    

    那么为什么向量的行为不同呢?为什么不能退货&dblvec[索引]? 正如@t.niese post中提到的,对vector的操作符函数的调用会识别出它是一个常量向量,因此它会自动返回 const double

    double& AddVecElem(int index) const {
        return dblvec[index]; // Compiler error - Expected double returns const double
    }
    

    我们想返回对这个变量的引用,但是返回的变量是一个常量。所以当你想回来的时候 双倍* const double* .

    即使您尝试四处调用vector.data(),它也会返回您 常数双* 而不是 -这就是向量和指针的区别。

    作为参考: Can const member function return a non-const pointer to a data member?