我有一个使用静态成员变量作为默认参数的令人困惑的问题。由于相同的语言构造在不同的地方工作,它可能与项目 (DLL) 的相互依赖关系有关。所以如果我的例子太复杂,请接受我的歉意,但我应该画出整个画面,因为我不知道出了什么问题。
我有一个基类(代表一种错误代码)
错误库文件
class ErrorBase
{
public:
typedef unsigned long ErrorCode;
/// here go the error codes. For reasons I do not want to explain, I cannot use an enumeration here.
static const ErrorCode ERROR_UNINITIALIZED;
static const ErrorCode ERROR_OK;
///...and so on
ErrorBase(ErrorCode theCode = ERROR_UNINITIALIZED);
};
Run Code Online (Sandbox Code Playgroud)
...在ErrorBase.cpp 中,我正在为代码赋值......
const ErrorBase::ErrorCode ErrorBase::ERROR_UNINITIALIZED = 0xffffffff;
const ErrorBase::ErrorCode ErrorBase::ERROR_OK = 0x0;
//.. and so on...
Run Code Online (Sandbox Code Playgroud)
ErrorBase 从一个 DLL 导出,该 DLL 为我们的项目提供了一些通用类
现在我正在为更具体的错误派生另一个错误类,它具有特定于特定类型错误的附加属性。类SpecificError 是不同DLL 的一部分,该DLL 链接到包含ErrorBase 的通用DLL。我没有包含 dllimport/dllexport shebang,但是我们到处都在使用它,并且它适用于所有情况。如果您有疑问,我可以编辑我的代码示例。
特定错误.h
class SpecificError : public ErrorBase
{
public:
static const ErrorCode SPECIFIC_ERROR_UNINITIALIZED;
static const ErrorCode SPECIFIC_ERROR_SOMETHING_WENT_WRONG;
SpecificError(ErrorCode theCode = SPECIFIC_ERROR_UNINITIALIZED);
};
Run Code Online (Sandbox Code Playgroud)
...在SpecificError.cpp中,我定义了这些值:
const SpecificError::ErrorCode SpecificError::SPECIFIC_ERROR_UNINITIALIZED = ErrorBase::ERROR_UNINITIALIZED;
Run Code Online (Sandbox Code Playgroud)
与 ErrorBase 一样,SpecificError 是从处理特定功能的 DLL 导出的。请注意,两个错误类都使用“UNINITIALIZED”值作为错误代码的默认值声明了一个构造函数。
现在我有一个依赖于两个 DLL 的程序,因此通过相应的导入库链接到它们。该程序包括ErrorBase.h 和SpecificError.h。ErrorCode.h 似乎没有任何问题,但是关于 SpecificError.h 我收到了
LNK2001 未解析的外部符号 SpecificError::ErrorCode SpecificError::SPECIFIC_ERROR_UNINITIALIZED 在 main.obj 中引用。
(备注:main.cpp 没有明确使用SpecificError,它只包含头文件)。
我能够通过从 SpecificError 构造函数中删除默认参数并声明一个默认构造函数来解决这个问题,该构造函数在其实现中调用 ErrorBase 的继承构造函数,并将 SPECIFIC_ERROR_UNINITIALIZED 传递给它。这使我假设符号 SPECIFIC_ERROR_UNINITIALIZED已正确声明和定义,但不能用作参数默认值。但是,这似乎仅适用于特定错误,在 ErrorBase 中一切似乎都很好。
工具集:我使用 Visual C++ 2017 作为编译器。
我重新创建了链接错误。对您的文件进行以下更改,根据您上面显示的代码片段,它应该可以正常工作:SpecificError.cpp
// I sent theCode to the Base class
SpecificError::SpecificError(ErrorCode theCode) : ErrorBase(theCode)
{
// ...
}
Run Code Online (Sandbox Code Playgroud)
在 ErrorBase.cpp 中,我刚刚添加了构造函数,但您可能已经有了这个:
ErrorBase::ErrorBase(ErrorCode theCode)
{
// ...
}
Run Code Online (Sandbox Code Playgroud)
完成此操作后,我还必须将静态常量的初始化从 .cpp 文件移至 .h。然后我通过执行以下操作来测试代码:
SpecificError e; // theCode ends up being 0xffffffff
SpecificError e1(20); // theCode ends up being 20
Run Code Online (Sandbox Code Playgroud)
我希望这对你有帮助。
这是我的 ErrorBase.cpp 的样子:
#pragma once
#include"ErrorBase.h"
#include<iostream>
ErrorBase::ErrorBase(ErrorCode theCode) {
std::cout << theCode << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
错误库.h:
#pragma once
class ErrorBase
{
public:
typedef unsigned long ErrorCode;
static const ErrorCode ERROR_UNINITIALIZED = 0xffffffff;
static const ErrorCode ERROR_OK = 0x0;
ErrorBase(const ErrorCode = ERROR_UNINITIALIZED);
};
Run Code Online (Sandbox Code Playgroud)
具体Error.cpp:
#pragma once
#include"SpecificError.h"
SpecificError::SpecificError(ErrorCode theCode) : ErrorBase(theCode)
{
}
Run Code Online (Sandbox Code Playgroud)
具体错误.h:
#pragma once
#include "ErrorBase.h"
class SpecificError : public ErrorBase
{
public:
static const ErrorCode SPECIFIC_ERROR_UNINITIALIZED = ErrorBase::ERROR_UNINITIALIZED;
static const ErrorCode SPECIFIC_ERROR_SOMETHING_WENT_WRONG = -42;
SpecificError(ErrorCode theCode = SPECIFIC_ERROR_UNINITIALIZED);
};
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
344 次 |
| 最近记录: |