为什么数组是常量?
Why is the array constant?
此问题是 的后续问题。我找到了一种使用数组为两个实例获取不同内存地址的方法。
vml.h
#pragma once
#include <iostream>
namespace vml {
// Vectors
template <typename in_type, const int in_length>
class vec {
public:
vec(in_type* in_data) {
std::cout << data << std::endl;
std::copy(in_data, in_data + in_length, data);
}
vec() {
data = nullptr;
}
in_type& operator()(int index) const {
_ASSERT(0 <= index && index < in_length);
return data[index];
}
private:
in_type data[in_length];
};
main.cpp
#include <memory>
#include "vml.h"
int main() {
int list[] = { 1,2,3 };
int list2[] = {2,4,6 };
vml::vec<int, 3> a(list);
vml::vec<int, 3> b(list);
a(1) = 3;
return 0;
}
但是,当我 运行 代码时,我得到一个错误
Error C2440 'return': cannot convert from 'const in_type' to 'in_type &'
因为 return 的值是 'data[index]' 这一定意味着它是常量,但是,我没有将它定义为常量,所以为什么会这样?
您在 return 类型的 operator()()
中错过了 const
in_type const & operator()(int index) const {
_ASSERT(0 <= index && index < in_length);
return data[index];
}
当您使用 const
修饰符声明成员函数时,内部的所有 class 成员在内部使用时变为常量
如果你想要非常量引用作为结果,你不应该在该成员函数上使用 const 修饰符:
in_type & operator()(int index) {
_ASSERT( 0 <= index && index < in_length);
return data[index];
}
对于初学者这个构造函数
vec() {
data = nullptr;
}
无效。数组是不可修改的左值。
这个成员函数
in_type& operator()(int index) const {
_ASSERT(0 <= index && index < in_length);
return data[index];
}
是常量成员函数。所以数组数据被认为是一个常量数组。
你可以像这样重载函数
const in_type& operator()(int index) const {
_ASSERT(0 <= index && index < in_length);
return data[index];
}
和
in_type& operator()(int index) {
_ASSERT(0 <= index && index < in_length);
return data[index];
}
在这种情况下在这个声明中
a(1) = 3;
会调用非常量成员函数
注意这个构造函数
vec(in_type* in_data) {
std::cout << data << std::endl;
std::copy(in_data, in_data + in_length, data);
}
不安全。至少参数应该有限定符 const
.
构造函数可以这样声明
vec( const in_type *in_data, size_t n );
为了修复它,您必须重载 operator() 两次
in_type const &operator()(int index) const {
_ASSERT(0 <= index && index < in_length);
return data[index];
}
in_type &operator()(int index) {
_ASSERT(0 <= index && index < in_lenght);
return data[index];
}
你必须这样做,因为当你创建一个 const 对象时,对象的任何成员都是 const,所以方法不能 return 引用但它必须 return 一个 const 引用,你即使使用非 const 方法也可以使用此方法,但您不能更改成员的值,这就是您需要 in_type operator()(int index)
的原因。
重要的是,当您将方法限定为 const 时,这意味着它也可用于 const 对象,因此它必须像处理 const 一样处理任何成员。
此问题是
vml.h
#pragma once
#include <iostream>
namespace vml {
// Vectors
template <typename in_type, const int in_length>
class vec {
public:
vec(in_type* in_data) {
std::cout << data << std::endl;
std::copy(in_data, in_data + in_length, data);
}
vec() {
data = nullptr;
}
in_type& operator()(int index) const {
_ASSERT(0 <= index && index < in_length);
return data[index];
}
private:
in_type data[in_length];
};
main.cpp
#include <memory>
#include "vml.h"
int main() {
int list[] = { 1,2,3 };
int list2[] = {2,4,6 };
vml::vec<int, 3> a(list);
vml::vec<int, 3> b(list);
a(1) = 3;
return 0;
}
但是,当我 运行 代码时,我得到一个错误
Error C2440 'return': cannot convert from 'const in_type' to 'in_type &'
因为 return 的值是 'data[index]' 这一定意味着它是常量,但是,我没有将它定义为常量,所以为什么会这样?
您在 return 类型的 operator()()
const
in_type const & operator()(int index) const {
_ASSERT(0 <= index && index < in_length);
return data[index];
}
当您使用 const
修饰符声明成员函数时,内部的所有 class 成员在内部使用时变为常量
如果你想要非常量引用作为结果,你不应该在该成员函数上使用 const 修饰符:
in_type & operator()(int index) {
_ASSERT( 0 <= index && index < in_length);
return data[index];
}
对于初学者这个构造函数
vec() {
data = nullptr;
}
无效。数组是不可修改的左值。
这个成员函数
in_type& operator()(int index) const {
_ASSERT(0 <= index && index < in_length);
return data[index];
}
是常量成员函数。所以数组数据被认为是一个常量数组。
你可以像这样重载函数
const in_type& operator()(int index) const {
_ASSERT(0 <= index && index < in_length);
return data[index];
}
和
in_type& operator()(int index) {
_ASSERT(0 <= index && index < in_length);
return data[index];
}
在这种情况下在这个声明中
a(1) = 3;
会调用非常量成员函数
注意这个构造函数
vec(in_type* in_data) {
std::cout << data << std::endl;
std::copy(in_data, in_data + in_length, data);
}
不安全。至少参数应该有限定符 const
.
构造函数可以这样声明
vec( const in_type *in_data, size_t n );
为了修复它,您必须重载 operator() 两次
in_type const &operator()(int index) const {
_ASSERT(0 <= index && index < in_length);
return data[index];
}
in_type &operator()(int index) {
_ASSERT(0 <= index && index < in_lenght);
return data[index];
}
你必须这样做,因为当你创建一个 const 对象时,对象的任何成员都是 const,所以方法不能 return 引用但它必须 return 一个 const 引用,你即使使用非 const 方法也可以使用此方法,但您不能更改成员的值,这就是您需要 in_type operator()(int index)
的原因。
重要的是,当您将方法限定为 const 时,这意味着它也可用于 const 对象,因此它必须像处理 const 一样处理任何成员。