在C ++中,作为类成员的引用应为const或非const

时间:2012-10-27 18:41:15

标签: c++ reference const const-cast

考虑以下最小例子。

#include <vector>

class Data
{
    std::vector<int>& v;
public:
    Data(std::vector<int>& _v) : v(_v) {}
    Data(const std::vector<int>& _v) : v(_v) {} // error!
};

int main()
{
    std::vector<int> v;
    const std::vector<int> c_v;
    Data d(v);
    Data const_d(c_v);

    return 0;
}

这不编译。 g++ -Wall以下的整个输出。

const.cpp: In constructor ‘Data::Data(const std::vector<int>&)’:
const.cpp:8:41: error: invalid initialization of reference of type ‘std::vector<int>&’ from expression of type ‘const std::vector<int>’

原因很清楚:const关键字对第8行中的演员表不满意。问题:我有时需要使用std::vector的Data类,但有时需要const std::vector。就像有两个课程:一个用于阅读Data,另一个用于阅读Data。但是,我不喜欢用几乎冗余的函数编写两个Data类。我的问题:

  • 你能否解决一下如何在main()中实现我的目标? C ++ 11解决方案也非常受欢迎:)
  • 这是iteratorconst_iterator
  • 的原因

2 个答案:

答案 0 :(得分:2)

const - 需要在编译时知道数据成员。如果“有时”需要引用const向量,有时需要非const,则应创建一个包含公共功能的基本抽象类的类层次结构,并将其继承为两个{{1 }}类:DataDataConstData将包含非Data向量,const将包含ConstData向量。这样您就不会复制任何逻辑,而两个单独的类将包含两个不同const的引用 -

以下是一个例子:

const

请注意,此类层次结构可能需要析构函数和各种复制构造函数,具体取决于用法。

答案 1 :(得分:1)

你得到的错误是:

foo.cpp: In constructor ‘Data::Data(const std::vector<int>&)’:
foo.cpp:8:44: error: invalid initialization of reference of type ‘std::vector<int>&’ from expression of type ‘const std::vector<int>’

...因为您正在尝试创建对您(Data)承诺您的来电者将被视为const的数据的非const引用。

这是一个将const引用声明为Data成员的解决方案:

#include <vector>

class Data
{
    const std::vector<int> &v;
public:
    Data(std::vector<int>& _v) : v(_v) {}
    Data(const std::vector<int>& _v) : v(_v) {} // error!
};

int main()
{
    std::vector<int> v;
    std::vector<int> c_v;
    Data d(v);
    Data const_d(c_v);

    return 0;
}

另一种选择是使用非参考成员:

#include <vector>

class Data
{
    std::vector<int> v;
public:
    Data(std::vector<int>& _v) : v(_v) {}
    Data(const std::vector<int>& _v) : v(_v) {} // error!
};