все. Я довольно новичок в 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 объявлен как ссылка на родительский класс, а не на производный класс, он задохнулся.
Теперь, когда я думаю об этом, мои рассуждения кажутся глупыми - я надеялся, что, поскольку функция была встроенной, она сможет проверять сами параметры, но, конечно, препроцессор всегда запускается перед компилятором. Но мне было интересно, знает ли кто-нибудь о каком-либо другом способе проверки такого рода во время компиляции.