Идиома копирования и замены для класса со ссылками на абстрактные классы

Я пытаюсь реализовать Идиому копирования и обмена для мой класс, поскольку мне нужно реализовать operator=, и поскольку он имеет ссылочные элементы, а ссылки могут быть назначены только один раз, я подумал, что вышеупомянутая идиома является допустимым обходным путем.

Но теперь я получаю ошибку сборки:

>c:\Program Files\Microsoft Visual Studio 10.0\VC\include\utility(102): error C2259: 'IVariables' : cannot instantiate abstract class
1>          due to following members:
1>          'IVariables::~IVariables(void)' : is abstract
1>          d:\svn.dra.workingcopy\serialport\IVariables.h(6) : see declaration of 'IVariables::~IVariables'
1>          'std::string &IVariables::operator [](const std::string &)' : is abstract
1>          d:\svn.dra.workingcopy\serialport\IVariables.h(7) : see declaration of 'IVariables::operator []'
1>          'unsigned int IVariables::getVariableLength(const std::string &) const' : is abstract
1>          d:\svn.dra.workingcopy\serialport\IVariables.h(8) : see declaration of 'IVariables::getVariableLength'
1>          Message.cpp(32) : see reference to function template instantiation 'void std::swap<IVariables>(_Ty &,_Ty &)' being compiled
1>          with
1>          [
1>              _Ty=IVariables
1>          ]

Это указывает мне сюда:

void Swap( CMessage& a, CMessage& b ){
    using std::swap;
    swap( a.m_bIgnoreIncoming, b.m_bIgnoreIncoming );
    swap( a.m_Variables, b.m_Variables );
}

Это функция Swap из идиомы, а m_Variables действительно является ссылкой на абстрактный класс. Разве нельзя поменять местами такие ссылки? Если для этого есть решение Boost, сообщите мне, поскольку я недавно начал его использовать.


person dario_ramos    schedule 12.01.2012    source источник
comment
См. Уродливое решение в stackoverflow.com/questions/15463321/   -  person the swine    schedule 17.03.2013
comment
Я видел гораздо более уродливые вещи. Но зачем вам это делать вместо того, чтобы просто использовать указатель? (должен быть неприкасаемый устаревший или сторонний код). Тем не менее, интересное чтение.   -  person dario_ramos    schedule 18.03.2013


Ответы (1)


Ссылки нельзя менять местами больше, чем их можно переназначить. swap будет пытаться поменять местами упоминаемые объекты (назначая их через временный объект, если используется значение по умолчанию std::swap). Поскольку они относятся к абстрактному базовому классу, это не удается, так как временный не может быть создан.

Если вам нужна переназначаемая ссылка, используйте вместо нее указатель.

person Mike Seymour    schedule 12.01.2012
comment
Итак ... Если у класса есть ссылочные члены, operator= не может быть правильно реализован? - person dario_ramos; 12.01.2012
comment
Верно ли это и для C ++ 11? - person dario_ramos; 12.01.2012
comment
@dario_ramos: Да; C ++ 11 также не позволяет переназначать ссылки. - person Mike Seymour; 12.01.2012
comment
Вы также можете использовать сутенера. Поместите свои ссылки в сутенер и поменяйте местами сутенера. - person wilhelmtell; 12.01.2012
comment
Комитет по стандартизации C ++ планирует исправить эту проблему в C ++ 2x, добавив ссылки на s-значения, такие как int&&& ;-) - person Johan Råde; 13.01.2012