c++ - 用作默认参数的静态成员会导致无法解析的外部

标签 c++

我在使用静态成员变量作为默认参数时遇到了一个令人困惑的问题。由于相同的语言构造在不同的位置工作,因此可能与项目 (DLL) 相互依赖关系有关。因此,如果我的示例太复杂,请接受我的歉意,但我应该绘制整个图景,因为我不知道出了什么问题。

我有一个基类(代表一种错误代码)

ErrorBase.h

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

...在 ErrorBase.cpp 中,我正在为代码分配值...

const ErrorBase::ErrorCode ErrorBase::ERROR_UNINITIALIZED = 0xffffffff;
const ErrorBase::ErrorCode ErrorBase::ERROR_OK = 0x0;
//.. and so on...

ErrorBase 是从 DLL 导出的,该 DLL 为我们的项目提供了一些通用类

现在我正在为更具体的错误派生另一个错误类,该错误类具有特定于特定错误类型的附加属性。 SpecificError 类是另一个 DLL 的一部分,该 DLL 链接到包含 ErrorBase 的通用 DLL。我没有包含 dllimport/dllexport shebang,但我们在各处都使用它,并且它在所有情况下都有效。如果您有疑问,我可以编辑我的代码示例。

SpecificError.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);
};

...并在 SpecificError.cpp 中定义这些值:

const SpecificError::ErrorCode SpecificError::SPECIFIC_ERROR_UNINITIALIZED = ErrorBase::ERROR_UNINITIALIZED;

与 ErrorBase 一样,SpecificError 是从处理特定功能的 DLL 中导出的。请注意,两个错误类都使用“UNINITIALIZED”值作为错误代码的默认值来声明构造函数。

现在我有一个程序依赖于这两个 DLL,因此通过相应的导入库链接到它们。该程序包括ErrorBase.h和SpecificError.h。 ErrorCode.h 似乎没有任何问题,但关于 SpecificError.h 我收到了

main.obj 中引用了 LNK2001 无法解析的外部符号 SpecificError::ErrorCode SpecificError::SPECIFIC_ERROR_UNINITIALIZED。

(备注:main.cpp 没有显式使用 SpecificError,它只包含头文件)。

我能够通过从 SpecificError 构造函数中删除默认参数并声明一个默认构造函数来解决该问题,该默认构造函数在其实现中调用 ErrorBase 的继承构造函数,并将 SPECIFIC_ERROR_UNINITIALIZED 传递给它。这让我假设符号 SPECIFIC_ERROR_UNINITIALIZED 已正确声明和定义,但不能用作参数默认值。然而,这似乎仅适用于 SpecificError,ErrorBase 中的一切似乎都很好。

工具集:我使用 Visual C++ 2017 作为编译器。

最佳答案

我重新创建了链接错误。对您的文件进行以下更改,根据上面显示的代码片段,它应该可以正常工作: 具体错误.cpp

// I sent theCode to the Base class
SpecificError::SpecificError(ErrorCode theCode) : ErrorBase(theCode)
{
// ...
}

在 ErrorBase.cpp 中,我刚刚添加了构造函数,但您可能已经有了:

ErrorBase::ErrorBase(ErrorCode theCode) 
{ 
// ...
}

完成此操作后,我还必须将静态常量的初始化从 .cpp 文件移至 .h。然后我通过执行以下操作测试了代码:

    SpecificError e; // theCode ends up being 0xffffffff
    SpecificError e1(20); // theCode ends up being 20

希望这对您有帮助。

这是我的 ErrorBase.cpp 的样子:

#pragma once
#include"ErrorBase.h"
#include<iostream>

ErrorBase::ErrorBase(ErrorCode theCode) {
    std::cout << theCode << std::endl;
}

ErrorBase.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);
};

具体错误.cpp:

#pragma once
#include"SpecificError.h" 

SpecificError::SpecificError(ErrorCode theCode) : ErrorBase(theCode)
{

}

具体错误.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);
};

关于c++ - 用作默认参数的静态成员会导致无法解析的外部,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59308563/

相关文章:

c++ - 如何使用安装在 macports 中的 gcc?

C++ - 简单形状面积计算器返回错误计算

c++ - Windows cpp 目标在较高分辨率下变慢

c++ - Arduino相当于VB WITH

c++ - 复制具有线程安全规则建议的非const参数的构造函数?

c++ - 从并发关联容器中删除 (concurrent_unordered_map)

c++ - 查询集成 Fortran 和 C++ 代码

c++ - 命名执行多个操作的方法

C++ move 复制构造函数和 move 赋值运算符

c++ - 在 C++ 复制省略期间如何管理内存?