【问题标题】:Linker errors with private members of class in header file头文件中类的私有成员的链接器错误
【发布时间】:2009-03-01 05:54:12
【问题描述】:

我正在尝试在 Visual Studio 2008 中构建一个项目。我遇到了一堆真正困扰我的链接器错误。我的应用程序是仅使用本机 ANSI C++ 的 Win32 控制台应用程序。

它们都是相同模式的链接器错误。 链接器错误与我在自己的头文件中定义的类的每个私有静态数据成员有关。

我猜这可能是我还不知道的 c++ 的一个简单事实?

示例: 我在文件Delays.cpp 中引用SingleDelay 成员类的函数定义中的SingleDelay 成员。 即:

SingleDelay::tick(void *output, void *input, int nbufferFrames)<br>{
   //.. code here<br>
   x = dry * castInput + wet * castInput;<br>
}

错误 38 错误 LNK2001: 无法解析的外部符号“private: static double SingleDelay::dry” (?dry@SingleDelay@@0NA) Delays.obj testall

Delays.h中SingleDelay的定义:

class SingleDelay{

    private:  
        static double dry; //% of dry signal<br>
        static double wet; //% of wet signal<br>
        static unsigned int delay; //Delay in milliseconds<br>
        static int delayCell; //Index in the delayBuffer of the delay to add<br>
        static double *delayBuffer; //Delay buffer is 1 second long at sample rate SAMPLE_RATE<br>
        static unsigned int bufferCell; //Pointer to the current delay buffer cell<br>

    public:

        //Tick function
        static void tick(void *output, void *input,int nBufferFrames);

        //Set and Get functions
        static void setSingleDelay(double tDry, double tWet, unsigned int tDelay);
        static void setSingleDelay(void);

        static void setDry(double tDry);
        static void setWet(double tWet);
        static void setDelay(unsigned int tDelay);

        static double getDry(){ return dry;}
        static double getWet(){ return wet;}
        static unsigned int getDelay(){ return delay;}

        static void initializeDelayBuffer(){
            destroyDelayBuffer();

            delayBuffer = new double[bufferLength];
        }
        static void destroyDelayBuffer(){
            delete[ ] delayBuffer;
        }
};

【问题讨论】:

  • 你能列出你得到的链接错误吗?
  • 耶哈,您可能想发布确切的链接器错误,因此我们可以为您提供建议,可能是什么原因。
  • 是的,我刚刚意识到,我添加了两个示例错误和一些相关代码。

标签: c++ include header linker


【解决方案1】:

它们都是相同模式的链接器错误。链接器错误与我在自己的头文件中定义的类的每个私有静态数据成员有关。

所有静态数据成员必须在 .cpp 文件某处中有定义。

错误 38 错误 LNK2001: 无法解析的外部符号“private: static double SingleDelay::dry” (?dry@SingleDelay@@0NA) Delays.obj testall

链接器告诉您该变量没有定义存储。此行必须恰好出现在一个 .cpp 文件中的某处:

double SingleDelay::dry = 0.0;

【讨论】:

    【解决方案2】:
    1. 也许您尚未添加库并将您使用的库的路径包含到项目定义中?
    2. C++ 错误总是很有趣。或不。无论如何,您是否在任何地方初始化静态变量?您需要在某处的 .cpp 文件中执行此操作。记住要小心使用静态变量。它们实际上是变相的全局变量,并且可以使未来的更改(例如多线程)变得更加困难。

    【讨论】:

    • 2.是的,我认为这是导致问题的静态变量的初始化。必须在 .cpp 中完成,还是可以在 .h 文件中的类定义之后完成?当我实际使用这个类时,初始化的值真的会被覆盖,所以它们对我来说不是很重要。
    • 至于使用静态,我将所有延迟类设为静态,因为出于我的目的,用户一次只使用一个,而且每次只使用一个,因此实例化该类似乎是多余的,可能实际上,它本身就给我带来了麻烦,而我通过静态方式避免了这些麻烦。
    • 好的,我尝试再次初始化变量,这次成功了。似乎我在第一次尝试时犯了一些小错误。感谢大家的帮助,有时需要别人推动你尝试两次=)。
    • 祝你好运!!!您可能要查看此链接:parashift.com/c++-faq-lite/ctors.html#faq-10.11 也请阅读它下面的项目,因为初始化静态变量的顺序是未定义的,如果您不小心可能会产生随机问题。
    • 请务必通过 grayfade 检查答案,因为它是正确的。当您在标头中定义静态属性时,您不会为它保留内存,只是声明变量(类似于 extern 声明)。您必须在一个编译单元中声明变量。
    【解决方案3】:

    也许错误在于您的静态字段可见范围,因为它们是私有的。 尝试编写在类定义中使用您的私有静态字段的代码,而不是超出您的类。 在你的类定义中写下这个方法:

    class SingleDelay{
     ...
    int tick(void *output, void *input, int nbufferFrames)
    { //.. code here
    x = dry * castInput + wet * castInput;
    }
     ...
    }
    

    【讨论】:

      【解决方案4】:

      您需要将 .cpp 和 .h 文件添加到 .vcproj 文件中。

      【讨论】:

      • 我不确定这意味着什么。我不使用文本编辑器或任何东西手动编辑我的 .vcproj 文件。我已将所有必要的包含文件拖放到我的项目的解决方案资源管理器中的头文件下拉菜单中。我还将 *.cpp 文件放在 Source Files 菜单中。
      • 我检查了一下,实际上我错过了一些 .cpp 文件,这些文件似乎可以清除我在 #2 的大部分链接器错误。我仍然不确定如何处理仍然得到的所有 #1 类型链接器错误。
      • 转到项目->添加文件,然后选择.cpp和.h而不是拖放。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-08-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-15
      • 2015-05-17
      • 1970-01-01
      相关资源
      最近更新 更多