自定义矢量类和按x,y,z引用元素



我正在尝试创建一个自定义向量类,用于在程序中进行线性代数计算。现在的类名是Rvec。以下是我正在尝试的:

我希望能够通过索引引用向量中的元素,但也希望能够通过在对象名称后键入.x来访问前三个元素(x,y,z((就像我有一个名为V的Rvec一样,我可以通过键入V.x来访问元素0,对y和z也类似(,因为这使得在我的一些程序中更容易理解。我已经考虑了一段时间,在网上也找不到任何明确的答案,但有几个想法都以失败告终。

我还重载了[]运算符,以便您可以直接访问元素(V[0]而不是V.values[0](

class Rvec {
public:
std::vector<float> values;
float operator[] (int index) { return values[index]; }
//option 1
//float x, y, z = values[0], values[1], values[2];
/*  option 2
float* x = &values[0];
float* y = &values[1];
float* z = &values[2];
// *Rvec.x
*/
/*  option 3
#define x values[0]
#define y values[1]
#define z values[2]
// Rvec.x
*/
//  option 4
/*   std::map<char, float> m;
Rvec() {
m.insert(pair<char, float>('x', 0));
m.insert(pair<char, float>('y', 0));
m.insert(pair<char, float>('z', 0));
}
float operator[](int index) {return m.at(index);}
float operator[](char key) { return m[key]; }*/
};

第一个选项只是将x、y、z初始化为浮点,但这显然不起作用,因为当实际元素更新时,它们不会更新值

第二种选择是将x、y、z定义为浮点指针,但我需要通过键入*V.x等来访问它们,这不是我想要的。

第三种选择是将x、y、z定义为宏。但是,这也带来了我不想处理的问题。

最后一个选项可能是使用映射并将前三个元素的键初始化为x、y、z。但在重载后引用它们将是V['x'],这甚至比指针更糟糕。

有没有什么方法可以引用这样的元素,只需键入V.x,并且值总是与它对应的元素相同?

我建议使用一些getter和setter:

class Rvec
{
public:
// getter
float x() const
{ return values[0];}
// setter
void x(float new_value)
{  values[0] = new_value;}
// If you trust the callers you return a reference:
float& y()
{  return values[1]; }
};

这将在代码中显示为:

Rvec r;
//...
std::cout << r.x() << "n";
float f = 0.0;
std::cout << "Enter x value: ";
std::cin >> f;
r.x(f);
std::cout << "Enter y value: ";
std::cin  >> r.y();

语法可能不如其他支持属性的语言优雅,但它应该可以解决您的问题。

注意:如果最后一对语句不起作用,请尝试以下操作:

std::cout << "Enter y value: ";
std::cin >> f;
r.y() = f;

最后一条语句是有效的,因为r.y()返回了对向量槽的引用。

@super在评论中给出的一个好的解决方案:

创建x、y、z作为常规浮点,使用前三个元素之后的所有元素的值向量,然后使[]运算符根据索引获取正确的变量。

class Rvec {
public:
float x, y, z;
std::vector<float> values;
float operator[] (int index) { 
switch (index) {
case 0:
return x;
case 1:
return y;
case 2:
return z;
default:
return values[index - 3];
}
}
};

最新更新