【问题标题】:Linker Error LNK2019链接器错误 LNK2019
【发布时间】:2010-09-09 20:28:11
【问题描述】:

我一直在玩模板函数,并制作了一个小记录器程序。我一直在尝试将其拆分为头文件/源文件,但我不断收到链接器错误。我知道这很简单,但我想不通。

此外,我在记录器标头中有​​一些令人信服的变量,这些变量的“适当”位置在哪里? (logStart、logEnd 等)

所有代码如下。

标题

#ifndef __moot_logger_hpp__
#define __moot_logger_hpp__


#include <iostream>
#include <fstream>
#include <string>

using std::ios;

namespace Moot
{
    struct Logger
    {
        Logger();
        ~Logger() {}


        template <class T>      
        void saveToFile(T type);

        template <typename T>
        Logger& operator<< (T type);


        /*
        Logger& operator<< (std::wstring wideStr)
        {
            saveToFile(Moot::convertWstringToString(wideStr));
            return *this;
        }
        */
    };


    /*
    namespace {
        Logger logStart;
        Logger& lStart = logStart;

        const char  logEnd = '\n';
        const char& lEnd   = logEnd;

        const char  logSpace = ' ';
        const char& lSpace   = logSpace;
    }
    */

}


#endif

来源

#include <Moot/logger.hpp>

Moot::Logger::Logger()
{
    std::ofstream logfile;
    logfile.open ("logfile.txt", ios::trunc);
    logfile << "LogFile - most recent at the bottom\n";
    logfile << "-----------------------------------\n \n";
    logfile.close();
}


template <typename T>
void Moot::Logger::saveToFile(T type)
{
    std::ofstream logfile;
    logfile.open ("logfile.txt", ios::in | ios::app);
    logfile << type;
    logfile.close();
}


template <typename T>
Moot::Logger& Moot::Logger::operator<< (T type) 
{
    saveToFile(type);
    return *this;
}


/*
Logger::Logger& operator<< (std::wstring wideStr)
{
    saveToFile(Moot::convertWstringToString(wideStr));
    return *this;
}
*/

主要

#include <Moot/logger.hpp>
#include <iostream>

int main()
{
    std::cout << "hello" << std::endl;

    Moot::Logger() << 12;
    //Moot::lStart.saveToFile(23);
    //Moot::lStart.operator << 13;

    return 0;
};

【问题讨论】:

  • 请注意以下划线开头的标识符是保留的。
  • 你不应该在标题中使用 using 指令;这样做只会以泪水告终。至于“方便变量”,如果它们只用在一个源文件中,你应该把它们放在那个源文件中。如果它们在多个源文件中使用,您应该将它们放在头文件中,也许在“详细”命名空间中。就个人而言,我不喜欢将全局实例用于记录器。将指针或引用(或智能指针,如果需要)传递给记录器的组件会更简洁(尽管有些人不同意这种观点)。
  • @Alexandre: &lt;nitpick&gt; 比这复杂一点。保留是以下划线后跟大写字母的所有标识符,全局名称空间中以下划线开头的所有标识符,以及在任何地方具有两个连续下划线的所有标识符。 &lt;/nitpick&gt; 不过,与其记住这些规则,不如完全避免前导下划线(当然,不止一个连续的下划线),所以基本上,我同意你的看法。 (+1 来自我。)
  • 是 James 提出的 using 指令(+1 来自我):stackoverflow.com/questions/2879555/…

标签: c++


【解决方案1】:

您需要阅读 C++ FAQ Lite 问题,"Why can't I separate the definition of my templates class from its declaration and put it inside a .cpp file?"

实际上,您需要在头文件中定义函数和类模板,而不是在 .cpp 文件中。

【讨论】:

    【解决方案2】:

    如果您想将定义与模板类的声明分开,而不是将定义移动到具有 hpp 或 tpp(文本编辑器并不总是正确处理)扩展名的单独文件中,并在声明文件的末尾添加定义文件的包含指令

    【讨论】:

      猜你喜欢
      • 2015-06-28
      • 2023-03-30
      • 2017-04-07
      • 1970-01-01
      • 1970-01-01
      • 2015-07-08
      • 1970-01-01
      • 1970-01-01
      • 2012-09-24
      相关资源
      最近更新 更多