我对类的const引用的理解是我们不能修改类的状态,即不能执行任何修改它的任何成员变量的动作。但请考虑以下代码。
#include <iostream>
#include <vector>
struct Vec {
Vec(std::vector<int>& v) : vec(v) {}
Vec(const Vec& v) : vec(v.vec) {
v.vec.resize(100);
}
std::vector<int>& vec;
};
int main() {
std::vector<int> x;
Vec v1(x);
Vec v2(v1);
v1.vec.resize(10, 0);
v2.vec[5] = 8;
std::cout << v1.vec[5] << std::endl;
return 0;
}
我使用带有-Wall标志的g ++:4.8.3编译了这段代码并进行了编译。我有两个问题。
Vec
复制构造函数中,我们将const引用传递给Vec v
。通过扩展v
的常量,v.vec
也应该是const std::vector<int>&
。然后如何将其复制到std::vector<int>
类型?答案 0 :(得分:3)
类的常量适用于其成员变量,但不适用于作为引用的成员变量的引用。这类似于指针成员,其中指针将是const,但不是它指向的内容。
答案 1 :(得分:1)
- 在Vec copy construtor中,我们将const引用传递给Vec v。通过扩展v的constness,v.vec也应该是 const std :: vector&amp; 。然后如何将其复制到类型std :: vector?
- 上述唯一合乎逻辑的方法是,如果一个类的常量不适用于它的成员变量。所以我的问题是一个类的常量对它的成员变量有什么影响?
醇>
这并不是const如何扩展。你将const粘贴在类型的背面上,而不是前面。请考虑以下代码......
struct foo {
foo() {}
int * i;
};
int main (void)
{
foo my_foo;
int * &a = my_foo.i;
const int * &b = my_foo.i;
int * const &c = my_foo.i;
const foo const_foo;
int * &d = const_foo.i;
const int * &e = const_foo.i;
int * const &f = const_foo.i;
return 0;
}
foo.cpp: In function ‘int main()’:
foo.cpp:12: error: invalid initialization of reference of type ‘const int*&’ from expression of type ‘int*’
foo.cpp:16: error: invalid initialization of reference of type ‘int*&’ from expression of type ‘int* const’
foo.cpp:17: error: invalid initialization of reference of type ‘const int*&’ from expression of type ‘int* const’
这表明const_foo.i
的类型为int * const
,与const int *
不同。类型int * const
没有声明它指向的数据没有变化,只是指针本身无法改变。
在您的示例中,v2.vec
的类型为std::vector<int> & const
。但是这种类型是没有意义的(并且是非法的),因为无论如何你都无法改变引用的别名。为此目的std::vector<int>
已经是const。
可能有const-ness继承,但您必须显式编写该规则。下面的代码很乐意拒绝编译,因为通过限制调用者使用getter来强制执行const限制来制作你正在寻找的契约...
#include <iostream>
#include <vector>
struct Vec {
Vec(std::vector<int>& v) : _vec(v) {}
Vec(const Vec& v) : _vec(v.vec()) {
v.vec().resize(100);
}
// How to make const-ness inherit...
std::vector<int> & vec() { return _vec; }
std::vector<int> const & vec() const { return _vec; }
private:
std::vector<int>& _vec;
};
int main() {
std::vector<int> x;
Vec v1(x);
Vec v2(v1);
v1.vec().resize(10, 0);
v2.vec()[5] = 8;
std::cout << v1.vec()[5] << std::endl;
return 0;
}
一旦你开始这样做,你会进入一个奇怪的领域,因为它允许我拨打std::vector<int> const & vec() const
,保存一个&#39; data-const&#39;引用_vec,然后让其他代码更改vec中的数据,违反了与早期代码的const契约。那里有许多地雷,这可能就是为什么语言没有内置这种常量继承的原因。