非 const 类处理的数据的 const 正确性
Posted
技术标签:
【中文标题】非 const 类处理的数据的 const 正确性【英文标题】:Const correctness for data handled by not const classes 【发布时间】:2017-06-07 15:44:43 【问题描述】:我想使用面向类的设计来高效、干净地处理嵌入式平台上的数据。我不应该在堆栈上创建新对象(或者至少是非常经济的),所以我打算将我的数据作为参考传递给辅助类并在其中操作它(也为了实现适当的封装)。
以下代码是我面临的问题的一个非常精简的示例。
#include "Vector.h"
void DoSomething(float* a1, const float* a2)
// some code
Vector v1(a1[0], a1[1], a1[2]);
Vector v2(a2[0], a2[1], a2[2]);
v1.MakeEqual(v2);
// more code
int main()
float x1[3] = 0, 0, 0 ;
float x2[3] = 1, 1, 1 ;
DoSomething(x1, x2);
return 0;
Vector
-Class 在头文件中定义:
#pragma once
class Vector
public:
Vector(float& _x, float& _y, float& _z) :x(_x), y(_y), z(_z)
Vector(const float& _x, const float& _y, const float& _z)
:x(const_cast<float&>(_x)), y(const_cast<float&>(_y)), z(const_cast<float&>(_z)) //works, but looks not good
~Vector();
void MakeEqual(const Vector& other)
x = other.x;
y = other.y;
z = other.z;
private:
float& x;
float& y;
float& z;
;
我的数据在外部某个地方定义(main
-function),然后作为指向函数DoSomething
的指针传递。在这个函数内部,向量对象被包裹在数据周围,以帮助做一些向量典型的事情(旋转、叉积等)。现在我想要 const 正确并传递不打算更改为 const
的数据,但是当创建向量 v2 时,我让编译器抱怨他 cannot convert argument 1 from 'const float' to 'float &'
。我明白他想说什么,但我该如何解决呢?向量方法仅在我在向量上使用时才有意义,但向量v2
的构造函数不知道我实际上并没有在处理 v2 的数据。
解决此问题的一种方法是在第二个构造函数中使用 const_cast
的代码中显示,但我觉得这不是一种好的风格,因为我正在丢弃我的合法 const 数据。另一种方法是定义第二类ConstVector
,但这似乎也很奇怪。
我不得不提一下,由于编译器的限制,我必须遵守C++03
标准,所以很遗憾我不能使用太现代的语言功能。 stl
-containers 也(可能)不可用,因为我无法控制分配内存的方式、时间和地点。
【问题讨论】:
您的MakeEqual
正在更改x,y,z
,因此您可以(能够)更改值。
虽然不建议在这种情况下使用,但您可以使用 class const_vector
之类的内容与 const 值一起使用。
【参考方案1】:
你有:
Vector(float& _x, float& _y, float& _z) :x(_x), y(_y), z(_z)
这不好用。例如,您不能使用:
Vector v1(0, 0, 0);
另外,你不能使用
Vector v1(a1[0], a1[1], a1[2]);
因为a1[0]
的计算结果为const float&
,而不是float&
。
那是设计糟糕的界面。将参数更改为简单值:
Vector(float _x, float _y, float _z) :x(_x), y(_y), z(_z)
【讨论】:
我猜 OP 希望Vector
s 充当包装器(可以更改原始数组),因此 Vector::Vector(float,float,float)
可能无法满足 OP 的需求(对于 v1
)。
@appleapple,我希望不会。在堆栈上使用临时对象,例如Vector
s,对于执行他们希望执行的计算类型没有多大帮助。我会等待 OP 澄清。
@appleapple,你是对的。我只使用 Vector 类以某种方式操作现有数据。在我这样做之后,我可以完全忽略该向量,因为它本身不包含数据。可以将数据作为建议的值传递,最后将向量运算的结果复制回数据。堆栈上的负载更多,但可能比我目前的解决方案更好......以上是关于非 const 类处理的数据的 const 正确性的主要内容,如果未能解决你的问题,请参考以下文章
防止 const 类函数在引用成员上调用非 const 类函数