всичко. Аз съм доста нов в C++ и пиша малка библиотека (най-вече за моите собствени проекти) в C++. В процеса на проектиране на йерархия на типове се натъкнах на проблема с дефинирането на оператора за присвояване.
Възприех основния подход, който в крайна сметка беше постигнат в тази статия , което е, че за всеки клас MyClass
в йерархия, получена от клас Base
, вие дефинирате два оператора за присвояване така:
class MyClass: public Base {
public:
MyClass& operator =(MyClass const& rhs);
virtual MyClass& operator =(Base const& rhs);
};
// automatically gets defined, so we make it call the virtual function below
MyClass& MyClass::operator =(MyClass const& rhs);
{
return (*this = static_cast<Base const&>(rhs));
}
MyClass& MyClass::operator =(Base const& rhs);
{
assert(typeid(rhs) == typeid(*this)); // assigning to different types is a logical error
MyClass const& casted_rhs = dynamic_cast<MyClass const&>(rhs);
try {
// allocate new variables
Base::operator =(rhs);
} catch(...) {
// delete the allocated variables
throw;
}
// assign to member variables
}
Частта, която ме интересува, е твърдението за равенство на типове. Тъй като пиша библиотека, където твърденията вероятно ще бъдат компилирани от крайния резултат, това ме накара да използвам схема, която изглежда по-скоро така:
class MyClass: public Base {
public:
operator =(MyClass const& rhs); // etc
virtual inline MyClass& operator =(Base const& rhs)
{
assert(typeid(rhs) == typeid(*this));
return this->set(static_cast<Base const&>(rhs));
}
private:
MyClass& set(Base const& rhs); // same basic thing
};
Но се чудех дали мога да проверя типовете по време на компилация. Разгледах Boost.TypeTraits и се доближих, като направих BOOST_MPL_ASSERT((boost::is_same<BOOST_TYPEOF(*this), BOOST_TYPEOF(rhs)>));
, но тъй като rhs е деклариран като препратка към родителския клас, а не към производния клас, той се задави.
Сега като се замисля, разсъжденията ми изглеждат глупави -- надявах се, че тъй като функцията е вградена, тя ще може да проверява самите действителни параметри, но разбира се препроцесорът винаги се изпълнява преди компилатора. Но се чудех дали някой знае за друг начин, по който мога да наложа този вид проверка по време на компилация.
Animal* animal = rand() % 2 ? new Dog() : new Cat();
- person UncleBens   schedule 12.04.2010