gpt4 book ai didi

c++ - 纯虚继承、多重继承、C4505

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:41:29 26 4
gpt4 key购买 nike

所以我有一个没有抽象方法的抽象基类。为了加强抽象性,我将(非平凡的)析构函数声明为纯虚拟的:

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 实例的代码块的输出是

    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;
}
};

当我尝试以这种方式实现两个不同的接口(interface)时出现问题:

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;
}
};

此时,在构建时,我收到以下警告:

warning C4505: 'AbstractClass::~AbstractClass' :unreferenced local function has been removed

然而,奇怪的是,输出仍然显示 AbstractClass::~AbstractClass() 被调用。

这是 MSVC9 (VS 2008) 中的错误吗?我可以安全地忽略此警告吗?

编辑:我也尝试过将纯虚方法定义与类定义分开,显然 = 0 {} 语法实际上无效。不幸的是,无论我是否指定 inline,C4505 仍然会出现。

因为我发现没有办法只为这些方法发出 #pragma 警告(警告是从代码的其他部分触发的),所以我可能不得不从中删除纯虚拟说明符AbstractClass 并依赖于使构造函数受到保护。这不是一个理想的解决方案,但它胜过重新构建类层次结构来绕过错误警告。

最佳答案

这是 MSVC++ 2010 及更早版本中的错误。代码实际得到即使编译器声称已删除代码,也会调用。好像是已在 MSVC++ 2012 中修复。其他编译器(如 gcc 或 clang)不会发出警告。根据 C++03 标准第 10.4.2 节(即使 MSVC++ 没有提示),语法“... = 0 {...}”是非法的,因为它已经被指出:

Note: a function declaration cannot provide both a pure-specifier and a definition

但是,定义一个纯虚拟析构函数一般来说并不违法,12.4.7 节指出:

A destructor can be declared virtual (10.3) or pure virtual (10.4); if any objects of that class or any derived class are created in the program, the destructor shall be defined. If a class has a base class with a virtual destructor, its destructor (whether user- or implicitly- declared) is virtual.

我禁用警告的方法是将以下行添加到标题中:

#if defined(_MSC_VER) && (_MSC_VER <= 1600)
# pragma warning(disable:4505)
#endif

如果您想在更多地方禁用警告,那么 #pragma warning( push )#pragma warning( pop ) 可能会有帮助。参见 http://msdn.microsoft.com/en-us/library/2c8f766e(v=vs.80).aspx

由于代码似乎被调用了,我认为您可以忽略警告。

关于c++ - 纯虚继承、多重继承、C4505,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12592865/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com