Giriş
İki nesnenin eşitliği için kullanılan metod imzasında her zaman const kullanmaya dikkat etmek lazım.
Birden fazla alana göre eşitliği kontrol etmek için std::tie kullanılabilir. Elimizde şöyle bir sınıf olsun.
İki nesnenin eşitliği için kullanılan metod imzasında her zaman const kullanmaya dikkat etmek lazım.
bool operator ==(const MyClass& u, const MyClass& v)
// ^^^^^ ^^^^^
// Note the use of `const`
Böylece temporary nesneler de kullanılabilir. Eğer yapmazsak aşağıdaki gibi unary minus operatörünün döndürdüğü temporary nesne için derleme hatası alırız.MyClass u = {3.14,-2.56};
MyClass expected = {-u.vx,-u.vy};
if(expected_vec == (-u)) // Derleme hatası
Birden fazla alana göre kontrolBirden fazla alana göre eşitliği kontrol etmek için std::tie kullanılabilir. Elimizde şöyle bir sınıf olsun.
struct Foo {
A a;
B b;
C c;
...
private:
auto tied() const { return std::tie(a, b, c, ...); }
};
eşittir öperatörü şöyle yazılabilir.bool operator==(Foo const& rhs) const { return tied() == rhs.tied(); }
Kendi operatör metodumuzu da yazabilirdik.struct Foo
{
int a,b,c,d,e,f;
bool operator==(const Foo& rhs) {
return std::tie(a,b,c,d,e,f) == std::tie(rhs.a,rhs.b,rhs.c,rhs.d,rhs.e,rhs.f);
}
};
Örnek
Kalıtım varsa operator==() metodu virtual bir metod çağırabilir. Şöyle yaparız
struct Identifier {
bool operator==(const Identifier& other) const {
return isEqual(other); //Burada virtual metodu çağır
}
private:
virtual bool isEqual(const Identifier& other) const = 0;
};
// Note: do not derive this class further (less dyncasts may logically fail).
struct UserIdentifier final : public Identifier {
int userId = 0;
private:
virtual bool isEqual(const Identifier& other) const override {
const UserIdentifier *otherUser = dynamic_cast<const UserIdentifier*>(&other);
return otherUser && otherUser->userId == userId;
}
};
// Note: do not derive this class further (less dyncasts may logically fail).
struct MachineIdentifier final : public Identifier {
int machineId = 0;
private:
virtual bool isEqual(const Identifier& other) const override {
const MachineIdentifier *otherMachine = dynamic_cast<const MachineIdentifier*>(&other);
return otherMachine && otherMachine->machineId == machineId;
}
};
Örnek
Kendi yazdığımız == operator() metodu ile built-in == metodları çakışabilir. Açıklaması şöyleIn the case of a == b and c == d, the built-in candidate operator==(int, int) (see [over.built]/13) competes with the operator== defined as a member of Foo<T>.Elimizde şöyle bir kod olsun.
template<class T>
class Foo
{
private:
T m_value;
public:
Foo();
Foo(const T& value):
m_value(value)
{
}
operator T() const {
return m_value;
}
bool operator==(const Foo<T>& other) const {
return m_value == other.m_value;
}
};
struct Bar
{
bool m;
bool operator==(const Bar& other) const {
return false;
}
};
Görmek için şöyle yaparız. Burada problem Foo sınıfının operator T() metoduna sahip olması. Derleyici Foo'yu bool'a çevirip mi karşılaştıracağını yoksa, Foo'nun operator==() metodunu mu çağıracağını bilemiyor.Foo<bool> a (true);
bool b = false;
if(a == b) {
// This is ambiguous
}
Foo<int> c (1);
int d = 2;
if(c == d) {
// This is ambiguous
}
Foo<Bar> e (Bar{true});
Bar f = {false};
if(e == f) {
// This is not ambiguous. Why?
}
Hiç yorum yok:
Yorum Gönder