So I have an abstract base class with no abstract methods. In order to enforce abstractness, I've declared the (non-trivial) destructor as pure virtual:
class AbstractClass
{
public:
AbstractClass()
{
std::wcout << L"AbstractClass::AbstractClass()" << std::endl;
}
virtual ~AbstractClass() = 0
{
std::wcout << L"AbstractClass::~AbstractClass()" << std::endl;
}
};
class ConcreteClass : public AbstractClass
{
public:
ConcreteClass()
{
std::wcout << L"ConcreteClass::ConcreteClass()" << std::endl;
}
virtual ~ConcreteClass()
{
std::wcout << L"ConcreteClass::~ConcreteClass()" << std::endl;
}
};
This builds and works as expected; the output for a code block that simply defines an instance of ConcreteClass is
AbstractClass::AbstractClass() ConcreteClass::ConcreteClass() ConcreteClass::~ConcreteClass() AbstractClass::~AbstractClass()
Now, when I have derive AbstractClass from another class used as an interface class, itself having a (trivial) virtual destructor (pure or otherwise), it still works:
class IAlpha
{
public:
virtual ~IAlpha() = 0 {}
};
class AbstractClass : public IAlpha
{
public:
AbstractClass()
{
std::wcout << L"AbstractClass::AbstractClass()" << std::endl;
}
virtual ~AbstractClass() = 0
{
std::wcout << L"AbstractClass::~AbstractClass()" << std::endl;
}
};
class ConcreteClass : public AbstractClass
{
public:
ConcreteClass()
{
std::wcout << L"ConcreteClass::ConcreteClass()" << std::endl;
}
virtual ~ConcreteClass()
{
std::wcout << L"ConcreteClass::~ConcreteClass()" << std::endl;
}
};
The problem arises when I attempt to implement two different interfaces in this manner:
class IAlpha
{
public:
virtual ~IAlpha() = 0 {}
};
class IBeta
{
public:
virtual ~IBeta() = 0 {}
};
class AbstractClass : public IAlpha, public IBeta
{
public:
AbstractClass()
{
std::wcout << L"AbstractClass::AbstractClass()" << std::endl;
}
virtual ~AbstractClass() = 0
{
std::wcout << L"AbstractClass::~AbstractClass()" << std::endl;
}
};
class ConcreteClass : public AbstractClass
{
public:
ConcreteClass()
{
std::wcout << L"ConcreteClass::ConcreteClass()" << std::endl;
}
virtual ~ConcreteClass()
{
std::wcout << L"ConcreteClass::~ConcreteClass()" << std::endl;
}
};
At this point, when building, I receive the following warning:
warning C4505: 'AbstractClass::~AbstractClass' : unreferenced local function has been removed
Strangely enough, however, the output still shows AbstractClass::~AbstractClass()
getting called.
Is this a bug in MSVC9 (VS 2008)? Can I safely ignore this warning?
Edit: I've tried separating the pure virtual method definitions from the class definition as well, as apparently the = 0 {}
syntax is not actually valid. Unfortunately, C4505 still shows up, whether I specify inline
or not.
Since I've found no way to #pragma
out this warning just for these methods (the warning gets triggered from other parts of the code), I may have to remove the pure virtual specifier from AbstractClass
and rely on making the constructors protected. Not an ideal solution, but it beats rearchitecting the class hierarchy to get around an erroneous warning.