在C#中,可以针对任何对象测试任何对象的相等性,因为所有对象都继承自Object。
在C ++中,情况并非如此。我想重载传入任何未知类的==运算符,并在运行时检查不等式,而不是编译时间。 (我收到错误binary '!=' : no operator found which takes a left-hand operand of type
)。
现在我想要这个用于TDD目的。
我该怎么做?
答案 0 :(得分:4)
在C#中,可以针对任何对象测试任何对象的相等性,因为所有对象都继承自Object。
这简直不正确。虽然每个类都继承了Equals
方法,但除非被覆盖,否则此方法不一定有意义。
你可以在C ++中实现相同的功能,但这是非常糟糕的练习,可能不是你想要的:
template <typename A, typename B>
bool equals(A const& a, B const& b) {
return reinterpret_cast<char const*>(&a) == reinterpret_cast<char const*>(&b);
}
......这将是您的后备案例(实施参考身份 1 )。现在,您可以添加类型实现适当运算符的一个(通过SFINAE):
template <typename T>
auto equals(T const& a, T const& b) -> decltype(a == b) {
return a == b;
}
然而,重申一下,既不建议也不普遍有用。这通常是荒谬的 - 要么你已经知道(以及如何)你可以比较你的对象,或者比较开始没有意义。
C#的设计非常糟糕。根本没有一般的“平等”概念,C#的Object
类型在这方面被过度指定。
1 对于struct
,C#实现成员相等,这可能更有意义,但同样通常不是想要的,并且引导效率非常低(因为它使用反射)。
答案 1 :(得分:2)
模仿C#机制给出(除了C#没有const):
#include <iostream>
class Object
{
public:
virtual ~Object() {}
virtual bool Equals(const Object& other) const {
// C# ReferenceEquals
return this == &other;
}
};
bool operator == (const Object& a, const Object& b) {
std::cout << " Object == Object ";
// C# ReferenceEquals
return &a == &b;
}
class Derived : public Object
{
public:
virtual bool Equals(const Object& other) const {
// C# does a test if the object is null - not needed in C++
const Derived* derived = dynamic_cast<const Derived*>(&other);
if(derived) return Equals(*derived);
else return false;
}
bool Equals(const Derived& other) const {
// Compare the members.
return true;
}
};
// C# Guideline: Overriding operator == in non-immutable types is not recommended
bool operator == (const Derived& a, const Derived& b) {
std::cout << "Derived == Derived ";
// C#: Test references conditions - not needed in C++:
// if (System.Object.ReferenceEquals(a, b)) return true;
// if (((object)a == null) || ((object)b == null)) return false;
return a.Equals(b);
}
// Test
template <typename A, typename B>
void compare(const char* what, const A& a, const B& b) {
std::cout << what << ": ";
std::cout << ((a == b) ? "True " : "False ");
std::cout << " Equals: " << ((a.Equals(b)) ? "True " : "False ") << '\n';
}
int main() {
Derived a;
Derived b;
Object& c = a;
Object& d = b;
compare("a == b", a, b);
compare("a == c", a, c);
compare("e == d", c, d);
}
输出:
a == b: Derived == Derived True Equals: True
a == c: Object == Object True Equals: True
e == d: Object == Object False Equals: True
我不建议在C ++中使用它。
备注(来自http://msdn.microsoft.com/en-us/library/ms173147%28v=vs.80%29.aspx)
Equals是一种虚方法,可以让任何类覆盖它 实现。任何代表值的类,基本上是任何类 值类型或作为组的一组值,例如复数 class,应该重写Equals。如果类型实现IComparable,它 应该重写等于。
默认情况下,运算符==测试引用相等性 确定两个引用是否表示相同的对象,因此引用 类型不需要实现operator ==以获得此功能 功能。当一个类型是不可变的时,意味着包含在中的数据 实例无法更改,重载operator ==进行比较 值相等而不是引用相等可能是有用的,因为,as 不可变对象,只要它们可以被认为是相同的 具有相同的价值。在非不可变类型中覆盖operator == 不推荐。