'Copy-and-Swap idiom for class with references to abstract classes
I'm trying to implement the Copy-and-Swap Idiom for my class, because I need to implement operator=, and since it has reference members, and references can only be assigned once, I thought that the aforementioned idiom was a valid workaround.
But now I'm getting a build error:
>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> ]
It points me here:
void Swap( CMessage& a, CMessage& b ){
using std::swap;
swap( a.m_bIgnoreIncoming, b.m_bIgnoreIncoming );
swap( a.m_Variables, b.m_Variables );
}
This is the Swap function from the idiom, and m_Variables is indeed a reference to an abstract class. Is it impossible to swap that kind of references? If there is a Boost solution for this, please tell me since I recently started using it.
Solution 1:[1]
Here is a short and complete example that illustrates swapping references to abstract type:
#include <iostream>
class AbstractBase
{
public:
virtual AbstractBase& clone() const = 0;
virtual AbstractBase& operator=(const AbstractBase& other) = 0;
virtual ~AbstractBase() = default;
};
class IntWrapper: public AbstractBase
{
public:
int val;
public:
IntWrapper(int v) : val{v} { }
IntWrapper& clone() const
{
IntWrapper* new_obj = new IntWrapper(val);
return *new_obj;
}
IntWrapper& operator=(const AbstractBase& other) override
{
auto context = static_cast<const IntWrapper&>(other);
val=context.val;
return *this;
}
~IntWrapper() override = default;
};
void swap(AbstractBase& a, AbstractBase& b)
{
AbstractBase& tmp = a.clone();
a = b;
b = tmp;
delete &tmp;
}
int main()
{
IntWrapper a(3), b(4);
std::cout << a.val << ", " << b.val << std::endl;
swap(a,b);
std::cout << a.val << ", " << b.val << std::endl;
return 0;
}
And output:
3, 4
4, 3
==1977==
==1977== HEAP SUMMARY:
==1977== in use at exit: 0 bytes in 0 blocks
==1977== total heap usage: 3 allocs, 3 frees, 73,744 bytes allocated
==1977==
==1977== All heap blocks were freed -- no leaks are possible
==1977==
==1977== For lists of detected and suppressed errors, rerun with: -s
==1977== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Ignatella |
