title: Pure virtual inheritance, multiple inheritance, and C4505
body: <p>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:</p>
  
  <pre><code>class AbstractClass
  {
  public:
    AbstractClass()
    {
      std::wcout &lt;&lt; L"AbstractClass::AbstractClass()" &lt;&lt; std::endl;
    }
    virtual ~AbstractClass() = 0
    {
      std::wcout &lt;&lt; L"AbstractClass::~AbstractClass()" &lt;&lt; std::endl;
    }
  };
  
  class ConcreteClass : public AbstractClass
  {
  public:
    ConcreteClass()
    {
      std::wcout &lt;&lt; L"ConcreteClass::ConcreteClass()" &lt;&lt; std::endl;
    }
    virtual ~ConcreteClass()
    {
      std::wcout &lt;&lt; L"ConcreteClass::~ConcreteClass()" &lt;&lt; std::endl;
    }
  };
  </code></pre>
  
  <p>This builds and works as expected; the output for a code block that simply defines an instance of ConcreteClass is</p>
  
  <pre>
  
      AbstractClass::AbstractClass()
      ConcreteClass::ConcreteClass()
      ConcreteClass::~ConcreteClass()
      AbstractClass::~AbstractClass()
  
  </pre>
  
  <p>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:</p>
  
  <pre><code>class IAlpha
  {
  public:
    virtual ~IAlpha() = 0 {}
  };
  
  class AbstractClass : public IAlpha
  {
  public:
    AbstractClass()
    {
      std::wcout &lt;&lt; L"AbstractClass::AbstractClass()" &lt;&lt; std::endl;
    }
    virtual ~AbstractClass() = 0
    {
      std::wcout &lt;&lt; L"AbstractClass::~AbstractClass()" &lt;&lt; std::endl;
    }
  };
  
  class ConcreteClass : public AbstractClass
  {
  public:
    ConcreteClass()
    {
      std::wcout &lt;&lt; L"ConcreteClass::ConcreteClass()" &lt;&lt; std::endl;
    }
    virtual ~ConcreteClass()
    {
      std::wcout &lt;&lt; L"ConcreteClass::~ConcreteClass()" &lt;&lt; std::endl;
    }
  };
  </code></pre>
  
  <p>The problem arises when I attempt to implement two different interfaces in this manner:</p>
  
  <pre><code>class IAlpha
  {
  public:
    virtual ~IAlpha() = 0 {}
  };
  
  class IBeta
  {
  public:
    virtual ~IBeta() = 0 {}
  };
  
  class AbstractClass : public IAlpha, public IBeta
  {
  public:
    AbstractClass()
    {
      std::wcout &lt;&lt; L"AbstractClass::AbstractClass()" &lt;&lt; std::endl;
    }
    virtual ~AbstractClass() = 0
    {
      std::wcout &lt;&lt; L"AbstractClass::~AbstractClass()" &lt;&lt; std::endl;
    }
  };
  
  class ConcreteClass : public AbstractClass
  {
  public:
    ConcreteClass()
    {
      std::wcout &lt;&lt; L"ConcreteClass::ConcreteClass()" &lt;&lt; std::endl;
    }
    virtual ~ConcreteClass()
    {
      std::wcout &lt;&lt; L"ConcreteClass::~ConcreteClass()" &lt;&lt; std::endl;
    }
  };
  </code></pre>
  
  <p>At this point, when building, I receive the following warning:</p>
  
  <pre>warning C4505: 'AbstractClass::~AbstractClass' :
  unreferenced local function has been removed</pre>
  
  <p>Strangely enough, however, the output still shows <code>AbstractClass::~AbstractClass()</code> getting called.</p>
  
  <p>Is this a bug in MSVC9 (VS 2008)?  Can I safely ignore this warning?</p>
  
  <p>Edit:  I've tried separating the pure virtual method definitions from the class definition as well, as apparently the <code>= 0 {}</code> syntax is not actually valid.  Unfortunately, C4505 still shows up, whether I specify <code>inline</code> or not.</p>
  
  <p>Since I've found no way to <code>#pragma</code> 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 <code>AbstractClass</code> and rely on making the constructors protected.  Not an ideal solution, but it beats rearchitecting the class hierarchy to get around an erroneous warning.</p>