Int& to const int -static vs dynamic-
Int& to const int -static vs dynamic-
class A
{
public:
A(int i = 25) {x = i;y=new int[i];for(int j=0;j<i;j++) y[j]=j;}
int& f() const {return x;}
int& operator[](int i) const {return y[i];}
private:
int x,*y;
};
int main()
{
A a(15);
cout << a[5];
cout << a.f();
return 0;
}
当我试图编译代码时,它显示
"Invalid initialization of reference of type int& from expression of type const int"
关于f()函数。
我理解它,因为它返回一个非const引用,指向函数声明为const的东西。但它的行为不应该与[]重载相同吗?
它还返回一个非const引用,指向函数声明为const的对象,但没有显示错误。有什么区别?
它告诉您不能从const
成员函数返回对数据成员的非const左值引用。你需要
const int& f() const {return x;}
如果需要,可以决定提供非const重载:
int& f() {return x;}
对于operator[]
,它不返回对数据成员的引用。不能通过operator[]
修改x
和y
,所以它实际上是const
成员函数。您可以决定不允许修改y
指向的数据,如果您的类建模一个数组,这将是有意义的。但这并不是严格必需的,编译器也没有理由强制执行它。
const int& operator[](int i) const {return y[i];}
int& operator[](int i) {return y[i];}
问题就在这里:
int& f() const {return x;}
你的函数被标记为const
,所以它只能被const
实例调用。但是,您返回一个非const
引用,因此,如果有效,您可以使用它来修改const
实例。编译器对此不满意。因此,f()
应该返回const int&
。
另一方面,int& operator[](int) const
编译,因为您返回对指针成员y
所指向的数据的引用,但您不能修改指针本身。换句话说,在const
实例上,指针y
是const
,即int * const y
,而不是数据。因此,按位const
-ness是保留的,但当然逻辑const
-ness不是,但是编译器只关心按位const
-ness。
要强制逻辑const
的正确性,一个选项是编写两个版本的operator[]
:
const int& operator[](int i) const {return y[i];}
和
int& operator[](int i) {return y[i];}
注意,第二个版本应该被标记为非const
,否则你会试图重载两个函数,它们只是返回类型不同。如果你想在非const
版本中避免代码重复,你可以通过const_cast
使用const
版本,如
int& operator[](int i)
{
return const_cast<int&>(const_cast<const A&>(*this)[i]); // use the const version
}
编辑
有人建议为类似指针的数据成员propagate_const
引入const
传播包装器,这实际上也会使数据指向const
,参见
在c++语言中,类的constness意味着其所有成员的直接constness (mutable
成员除外)。然而,类的constness不会传播到指针成员所指向的数据或引用成员所引用的数据。指向/引用的数据不是类的一部分,它的constness不受类的constness的影响。
在您的示例中,将成员函数声明为const
使其将成员x
和y
视为const
。但是,y
所指向的数据并没有变成const
,例如,*y
和y[i]
都不是const
。
- 在VS代码中交叉编译Windows与Linux上的MinGW的SDL程序
- 如何为模板化对象创建模板向量?VS正在投掷C3203
- 为什么即使使用-cudart-static进行编译,库用户仍然需要链接到cuda运行时
- 数据成员SFINAE的C++17测试:gcc vs clang
- 为什么在Windows上的VS 2019和Clang 9中"size_t"在没有标题的情况下工作
- 在for循环中使用auto vs decltype(vec.size())来处理字符串的向量
- 正在VS调试器中监视映射条目
- Confusion: decltype vs std::function
- 将IBM Rhapsody模型集成到VS 2019中
- VS Code "command":"make"与终端窗口中的命令行"make"不同
- 使用VS Code和CMake Tools运行自定义命令
- 修改 VS Code 中的默认C++代码段
- 继承自 std::true_type vs static constexpr const bool 成员
- static const std::map<string, int> vs if-elseif
- getInstance - Class vs Method static
- c++11 std::array vs static array vs std::vector
- static assert - C++ concepts vs static_assert
- 引用 MFC 的多个项目:"use mfc in a static library" vs "use mfc in a shared dll" ?
- std::string vs char array for static const
- Int& to const int -static vs dynamic-