【发布时间】:2012-09-26 00:12:14
【问题描述】:
所以我有一个没有抽象方法的抽象基类。为了强制执行抽象,我将(非平凡的)析构函数声明为纯虚拟:
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 {} 语法实际上是无效的。不幸的是,无论我是否指定inline,C4505 仍然出现。
由于我没有找到#pragma 仅针对这些方法发出此警告的方法(警告从代码的其他部分触发),我可能必须从AbstractClass 中删除纯虚拟说明符并依赖使构造函数受到保护。这不是一个理想的解决方案,但它胜过重新架构类层次结构以规避错误警告。
【问题讨论】:
标签: c++ destructor multiple-inheritance pure-virtual