C++ 不同类型的对称二元运算符
我正在学习 C++,我想知道是否可以深入了解创建适用于两种不同类型实例的二元运算符的首选方法。 这是我用来说明我的担忧的一个例子:
class A;
class B;
class A
{
private:
int x;
public:
A(int x);
int getX() const;
int operator + (const B& b);
};
class B
{
private:
int x;
public:
B(int x);
int getX() const;
int operator + (const A& A);
};
A::A(int x) : x(x) {}
int A::getX() const { return x; }
// Method 1
int A::operator + (const B& b) { return getX() + b.getX(); }
B::B(int x) : x(x) {}
int B::getX() const { return x; }
// Method 1
int B::operator + (const A& a) { return getX() + a.getX(); }
// Method 2
int operator + (const A& a, const B& b) { return a.getX() + b.getX(); }
int operator + (const B& b, const A& a) { return a.getX() + b.getX(); }
#include <iostream>
using namespace std;
int main()
{
A a(2);
B b(2);
cout << a + b << endl;
return 0;
};
如果我想在两种类型之间具有对称性,哪种方法是上面代码中的最佳方法。 选择一种方法而不是另一种方法是否存在任何可能的危险? 这会随着返回类型的变化而变化吗? 请解释! 谢谢你!
I am learning C++ and I was wondering if I could gain some insight into the preferred way of creating binary operators that work on instances of two different types. Here is an example that I've made to illustrate my concerns:
class A;
class B;
class A
{
private:
int x;
public:
A(int x);
int getX() const;
int operator + (const B& b);
};
class B
{
private:
int x;
public:
B(int x);
int getX() const;
int operator + (const A& A);
};
A::A(int x) : x(x) {}
int A::getX() const { return x; }
// Method 1
int A::operator + (const B& b) { return getX() + b.getX(); }
B::B(int x) : x(x) {}
int B::getX() const { return x; }
// Method 1
int B::operator + (const A& a) { return getX() + a.getX(); }
// Method 2
int operator + (const A& a, const B& b) { return a.getX() + b.getX(); }
int operator + (const B& b, const A& a) { return a.getX() + b.getX(); }
#include <iostream>
using namespace std;
int main()
{
A a(2);
B b(2);
cout << a + b << endl;
return 0;
};
If I would like to have symmetry among the two types, which method is the best approach in the above code. Are there any possible dangers in choosing one method over the other? Does this vary with the return type? Please explain! Thank you!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
发布评论
评论(4)
方法 2 的主要论点是,您可以对两个操作数进行隐式类型转换,而不仅仅是第二个操作数。 这可能会避免某些地方的混乱。
说到这里,您的示例代码通过两个类上的 1-arg 构造函数定义了从 int 到 A 以及从 int 到 B 的隐式转换。 这可能会导致以后出现歧义。 但如果你为了简洁而省略了“明确的”,那也很公平。
不过,我同意 Uri 的警告:如果您发现自己这样做,那么您编写的 API 可能会让其他人感到困惑。 为什么A加B是int? 对于用户来说,添加 a 和 b,而不是自己调用 getX 并添加结果,真的会让事情变得更容易吗?
是因为用户非常清楚 A 和 B 是整数的包装吗? 如果是这样,那么另一个选择是通过运算符 int() 公开从 A 到 int 和 B 到 int 的转换。 然后 a+b 会出于合理的原因返回一个 int ,并且您也会得到所有其他算术运算符:
#include <iostream>
struct A {
int x;
explicit A(int _x) : x(_x) {}
operator int() {
return x;
}
};
struct B {
int x;
explicit B(int _x) : x(_x) {}
operator int() {
return x;
}
};
int main() {
A a(2);
B b(2);
std::cout << a + b << "\n";
std::cout << a - b << "\n";
}
我在评论中读到您的预期用途是添加向量和矩阵。 也许您应该考虑仅使用向量为一维矩阵的矩阵。 那么你只剩下一种类型和一组运算符:
matrix operator*( matrix const& a, matrix const& b );
matrix operator+( matrix const& a, matrix const& b ); // and so on
如果你想保留向量类,那么你应该考虑是否还想要一个转置向量(也许转置只是向量的内部属性)。
这组操作并不是真正对称的:
向量 * 矩阵 = 向量 矩阵 * 向量_t = 向量_t 矩阵 * 矩阵 = 矩阵 矢量_t * 向量 = 矩阵 向量*向量_t = int
并且您应该提供这三个操作(假设转置是向量的属性):
vector operator*( vector const& v, matrix const& m );
vector operator*( matrix const& m, vector const& v );
matrix operator*( matrix const& m1, matrix const& m2 );
matrix operator*( vector const& v1, vector const& v2 ); // possibly 1x1 matrix, you cannot overload changing only return value
如果可能,全部作为自由函数。 即使上述集合不对称,现实世界也不是对称的,并且您的用户也会期望它。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
最好的方法是定义(在任一类之外)
int operator+ (const A& a, const B& b)
,并在需要时将其设为两个类的友元函数。 另外,定义使其对称。
The best way is to define (outside of either class)
int operator+ (const A& a, const B& b)
, and make it a friend function of both classes if needed. In addition, defineTo make it symmetric.