c++ - g++ 使用模板时出现重复符号错误(菜鸟问题)

标签 c++ templates compiler-errors g++

所以我尝试选择 C++,为此我决定使用模板编写一个通用的 Group 类,它将 Type 和 size 作为模板参数:

在 group.h 中:

#ifndef __GROUP_H
#define __GROUP_H
#define MAX_SIZE 10

/**********************************************************
 * Define a Group class that handles a collection of members
 * of some Type
 **********************************************************/
template <class Type, int max>
class Group {
  private:
      std::string name;
      int count, size;
      Type * members[max];

  public:
      Group();
      Group(const std::string & _name);
      ~Group();

      // display instance info
      virtual void show();

      // add member
      void add_member(Type &);

      // list memebers
      void list();

      // name setter/getter
      void set_name(const std::string &);
      const std::string & get_name();

};

#endif

group.cc:

/**********************************************************
 * class methods for Group
 **********************************************************/
template <class Type, int max>
Group<Type, max>::Group() : count(0), size(max), name("New Group") {};

template <class Type, int max>
Group<Type, max>::Group(const std::string & _name) : name(_name), count(0), size(max) {};

template <class Type, int max>
Group<Type, max>::~Group() {
  int i = 0; 
  while(i < this->count) {
    delete this->members[i];
    ++i;
  }
}

template <class Type, int max>
void Group<Type, max>::show() {
    std::cout << "<#Group - Name: " << this->name << ", Members: " << this->count << "/" << this->size << " >\n";
}

template <class Type, int max>
void Group<Type, max>::add_member(Type & member) {
    if (this->count < this->size) {
        this->members[this->count] = &member;
        this->count++;
    } else {
        std::cout << "Error - this Group is full!\n";
    }
}

template <class Type, int max>
void Group<Type, max>::list() {
    int i = 0;
    std::cout << "The following are members of the Group " << this->name <<":\n";
    // assumes the member has a show() method implemented
    while (i < this->count) {
        std::cout << i << ". ";
        (this->members[i])->show();
        ++i;
    }
}

template <class Type, int max>
void Group<Type, max>::set_name(const std::string & _name) {
    this->name = _name;
}

template <class Type, int max>
const std::string & Group<Type, max>::get_name() {
  return this->name;
}

我还实现了一个 Person 类和一个 Employee 类(继承自 Person),它们都可以工作并具有 show() 方法。

我的主图是这样的:

test.cc

#include <iostream>
#include "group.h" // this also has the declarations and implementation for Person/Employee

int main (int argc, char const *argv[])
{
    // Person ctor takes name and age
    Person p1("John", 25); 
    Person p2("Jim", 29);

    // Group takes name to init
    Group <Person, 5> g("Ozcorp");
    g.add_member(p1);
    g.add_member(p2);
    g.list();    
}

我用一个简单的 Makefile 编译了它:

test: test.cc group.o
    g++ -o test test.cc group.o

group.o: group.h group.cc
    g++ -c group.cc

最后(哇),当我用 ./test 运行它时,出现了以下错误:

Undefined symbols:
  "Group<Person, 5>::list()", referenced from:
      _main in ccaLjrRC.o
  "Group<Person, 5>::Group(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)", referenced from:
      groups()    in ccaLjrRC.o
      _main in ccaLjrRC.o
  "Group<Person, 5>::~Group()", referenced from:
      groups()    in ccaLjrRC.o
      _main in ccaLjrRC.o
      _main in ccaLjrRC.o
  "Group<Person, 5>::add_member(Person&)", referenced from:
      _main in ccaLjrRC.o
      _main in ccaLjrRC.o
ld: symbol(s) not found
collect2: ld returned 1 exit status
make: *** [test] Error 1

如果您做到了这一点 - 谢谢 - 我会很感激您能提供一些关于为什么会发生这种情况的见解。我试图从代码中尽可能多地分享(显然),所以请原谅我,如果它太多了。源代码是在 mac osx 10.6.4 上用 g++ 4.2.1 编译的。此外,我们将不胜感激任何风格/良好的编码习惯提示。谢谢!

最佳答案

模板化类成员定义不会进入 .cc/.cpp 文件。 它们进入 .h 或 .h 包含的 .hpp/.hxx 文件 原因是 .cc/.cpp 文件用于构建对象文件。 但是,对于模板化代码,在替换模板化参数之前无法创建对象。因此,它们的实现必须可用于实例化它们的所有代码片段:在类似 .h 的文件中。

关于c++ - g++ 使用模板时出现重复符号错误(菜鸟问题),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3318915/

相关文章:

c++ - 指针间接寻址对效率的影响有多大?

c++ - 如何在 C++ 中删除一行?

C++ decltype,带有if语句,用于递归函数

c++:异步抛出 C2752 和 C2064

c - 如何在 Linux 工作中使用 "make and building executables"

java - 编译 Netbeans Java 程序

c++ - 创建一个 vector 作为函数调用参数

c++ - Delphi与C++dll通信(参数)

c++ - 使用模板访问成员变量

C++ 尝试使用#ifndef 和#include 语句