所以我有一个没有抽象方法的抽象基类。为了强制执行抽象,我将(非平凡的)析构函数声明为纯虚拟:
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;
}
};
这可以按预期构建和工作;简单定义 ConcreteClass 实例的代码块的输出是
抽象类::抽象类() 具体类::具体类() ConcreteClass::~ConcreteClass() AbstractClass::~AbstractClass()
现在,当我从另一个用作接口类的类派生 AbstractClass 时,它本身具有(微不足道的)虚拟析构函数(纯或其他),它仍然有效:
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;
}
};
当我尝试以这种方式实现两个不同的接口时,就会出现问题:
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;
}
};
此时,在构建时,我收到以下警告:
警告 C4505:“AbstractClass::~AbstractClass”: 未引用的本地函数已被删除
然而,奇怪的是,输出仍然显示AbstractClass::~AbstractClass()
被调用。
这是 MSVC9(VS 2008)中的错误吗?我可以放心地忽略此警告吗?
编辑:我也尝试将纯虚拟方法定义与类定义分开,因为显然= 0 {}
语法实际上是无效的。不幸的是,无论我是否指定,C4505 仍然出现inline
。
由于我找不到#pragma
仅针对这些方法来消除此警告的方法(警告是从代码的其他部分触发的),因此我可能必须从中删除纯虚拟说明符AbstractClass
并依赖于使构造函数受到保护。这不是一个理想的解决方案,但它胜过重新架构类层次结构以绕过错误警告。