3

考虑以下最小示例。

#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 行中的演员表感到不安。问题:我确实有时需要 Data 类std::vector,但有时需要const std::vector。就像有两门课:一门用于阅读Data,另一门用于阅读Data。但是,我不喜欢编写两个具有几乎冗余功能的 Data 类。我的问题:

  • 你能给出一个很好的解决方案来说明我如何实现我尝试做的事情main()吗?C++11 解决方案也很受欢迎:)
  • 这是iterator和的原因const_iterator吗?
4

2 回答 2

2

const需要在编译时知道数据成员的特性。如果您“有时”需要对const向量的引用,有时需要对向量的引用const,那么您应该使用包含通用功能的基本抽象类创建一个类层次结构,并在两个Data类中继承它:DataConstData. 将Data包含一个非const向量,并且ConstData将包含一个const向量。这样你就不会重复任何逻辑,而两个单独的类将包含两个不同的引用const

这是一个例子:

class AbstractData {
public:
    // Common functions use vect() and const_vect()
    void common_function1();
    void common_function2();
protected:
    virtual vector<int>& vect() const = 0;
    virtual const vector<int>& const_vect() const = 0;
};

class Data : public AbstractData {
    vector<int>& v;
public:
    Data(vector<int>& _v) : v(_v) {}
protected:
    vector<int>& vect() const {
        return v;
    }
    const vector<int>& const_vect() const {
        return v;
    }
};

class ConstData : public AbstractData {
    const vector<int>& v;
    vector<int> temp;
public:
    ConstData(const vector<int>& _v) : v(_v) {}
protected:
    vector<int>& vect() const {
        return temp; // You can choose to throw an exception instead
    }
    const vector<int>& const_vect() const {
        return v;
    }
};

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

于 2012-10-27T18:49:08.297 回答
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引用声明为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!
};
于 2012-10-27T18:45:18.533 回答