【问题标题】:C++, array declaration, templates, linker errorC++、数组声明、模板、链接器错误
【发布时间】:2012-10-24 19:08:16
【问题描述】:

我的软件中有一个链接器错误。我正在使用以下基于 h、hpp、cpp 文件的结构。有些类是模板化的,有些不是,有些有函数模板。 SW 包含数百个包含的类...

声明:

test.h
#ifndef TEST_H
#define TEST_H

class Test
{
   public: 
        template <typename T>
        void foo1();

        void foo2 ();
};

#include "test.hpp" 

#endif

定义:

test.hpp
#ifndef TEST_HPP
#define TEST_HPP

template <typename T>
void Test::foo1() {}

inline void Test::foo2() {} //or in cpp file

#endif

CPP 文件:

test.cpp
#include "test.h"

void Test::foo2() {} //or in hpp file as inline

我有以下问题。变量 vars[] 在我的 h 文件中声明

test.h
#ifndef TEST_H
#define TEST_H

char *vars[] = { "first", "second"...};

class Test
{
    public: void foo();
};

#include "test.hpp"

#endif

并用作在 hpp 文件中作为内联定义的 foo() 方法内的局部变量。

test.hpp
#ifndef TEST_HPP
#define TEST_HPP


inline void Test::foo() {
    char *var = vars[0];   //A Linker Error
}

#endif

但是,出现以下链接器错误:

Error   745 error LNK2005: "char * * vars" (?vars@@3PAPADA) already defined in main.obj

如何以及在何处声明 vars[] 以避免链接器错误?包括后

#include "test.hpp"

声明已经晚了……

正如我所写,该软件包含很多cpp,和hpp文件相互包含(所有包含都已检查)。无法发送整个示例...

main.obj 代表一个包含主类的文件。

【问题讨论】:

  • Ifndef 还是 ifndex?您是否收到有关该处理器指令的警告...?如果它不能防止双重包含可能会这样做。另外,尝试使用 -E 进行编译以找出第二个定义的来源。
  • @RutgersMike:ifndef,当然,谢谢,这里只是一个错字...
  • 只是代码中的一些拼写错误。 ifndex 到 ifndef,void foo2() 需要 ';'到底。从 *vars[]...中删除 '...'...
  • @billz。谢谢,检查并纠正(也许),。不用编译器编写...
  • err,那么 test2.obj 呢???

标签: c++ templates linker-errors


【解决方案1】:

在带有外部链接的标题中声明vars

extern const char* vars[];

并在一个源文件中定义它

const char* vars[] = {"foo", "bar"};

注意const,从字符串文字到char* 的转换已被弃用。你现在拥有它的方式,你违反了One definition rule(你在你的标题包含的每个翻译单元中重新定义vars)。

【讨论】:

    【解决方案2】:

    我认为你只需要在 test.hpp 中使用这个

    extern char *vars[];
    

    ...这在 test.cpp 中

    char *vars[] = { "first", "second"...};
    

    【讨论】:

      【解决方案3】:

      我假设您没有声明两个名为Test 的类。如果你是,那将给你带来无穷无尽的问题。你不能这样做。

      所以我假设class Test 的完整声明如下所示:

      class Test
      {
       public:
         void foo();
      
         template <typename T>
         void foo1();
      
         void foo2 ();
      };
      

      如果是这样,那么你的问题就很清楚了。

      您需要更改vars 的定义。你需要在test.h

      extern char *vars[];
      

      这个在test.cpp:

      char *vars[] = { "first", "second"...};
      

      否则编译器会认为你试图在每个文件中声明一个新版本的vars

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-04-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多