如何在const成员函数中使用非const成员函数?

Sam*_*mik 1 c++ const

以下是一个简单的C++结构和一个3D矢量和3x3矩阵的类.正如您所看到的那样,下标运算符对它们都是重载的.我为了能够分配到像那些成员返回从他们的数据成员参考vec[0] = 5.0;,mat[0] = vec3(2.0);mat[0][0] = 3.0;等.现在,我宣布另一家运营商的mat3,这不应该修改矩阵本身,而是应该回到一个新的加号(+)运算符矩阵作为总和.如何将此非修改+运算符设为const

向量

struct vec3 {
    typedef double value_type;
    vec3::value_type x, y, z;

    vec3(const vec3::value_type x,
         const vec3::value_type y,
         const vec3::value_type z)
    : x{x}, y{y}, z{z} {}

    vec3(const vec3::value_type w)
    : vec3(w, w, w) {}

    vec3()
    : vec3(0.0) {}

    // this works because [] operator is not used
    vec3 operator+(const vec3& v) const {
        return vec3(this->x + v.x, this->y + v.y, this->z + v.z);
    }

    vec3::value_type& operator[](const std::size_t index) {
        switch(index) {
        case 0:
            return x;
        case 1:
            return y;
        case 2:
            return z;
        default:
            throw std::invalid_argument("vec3 supports upto 3(0-2) elements");
        }
    }
};
Run Code Online (Sandbox Code Playgroud)

矩阵

class mat3 {
    std::array<vec3,3> val;
public:
    using vtype = vec3::value_type;
    mat3(const vtype v00, const vtype v01, const vtype v02,
         const vtype v10, const vtype v11, const vtype v12,
         const vtype v20, const vtype v21, const vtype v22) {
        val[0][0] = v00; val[0][1] = v10; val[0][2] = v20;
        val[1][0] = v01; val[1][1] = v11; val[1][2] = v21;
        val[2][0] = v02; val[2][1] = v21; val[2][2] = v22;
    }

    mat3(const vtype m[3][3]) {
        for(std::size_t i = 0; i < 3; ++i) {
            for(std::size_t j = 0; j < 3; ++j) {
                val[i][j] = m[j][i];
            }
        }
    }

    mat3(const vtype v)
    : mat3(v, v, v,
           v, v, v,
           v, v, v) {}

    mat3()
    : mat3(0.0) {}

    // how to make it `const`
    mat3 operator+(const mat3& m) {
        mat3 t;
        for(std::size_t i = 0; i < 3; ++i) {
            t[i] = val[i] + m[i];
        }
        return std::move(t);
    }

    vec3& operator[](const std::size_t index) {
        switch(index) {
        case 0:
            return val[0];
        case 1:
            return val[1];
        case 2:
            return val[2];
        default:
            throw std::invalid_argument("mat3 supports upto 3(0-2) vec3");
        }
    }
};
Run Code Online (Sandbox Code Playgroud)

son*_*yao 7

您可以(并且应该)添加const版本operator[],然后您可以创建operator+const,operator[]将在其中调用const版本.

vec3& operator[](const std::size_t index) {
    ...
}
const vec3& operator[](const std::size_t index) const {
~~~~~                                           ~~~~~
    ...
}
Run Code Online (Sandbox Code Playgroud)

请注意,您可以重载const和非const成员函数.

请参阅const-,volatile-和ref-限定的成员函数(强调我的)

非静态成员函数可以与被声明const,volatileconst volatile限定符(此限定符在函数声明的函数的名称后出现).不同的cv限定函数具有不同的类型,因此可能相互重载.

在cv限定函数的主体中,this指针是cv限定的,例如在const成员函数中,只能正常调用其他const成员函数.(如果应用非const成员函数const_cast或通过不涉及的访问路径,仍可能会调用非const成员函数this.)

  • @Samik是的,你可以,const和非const成员函数都很重要,有一个隐含的`this`具有不同的类型. (3认同)