c++ - 为什么从基模板类继承并将两个类文件放在单独的头文件中时会出现重定义错误?

标签 c++ class templates inheritance

我的基本模板类在 Base.h 中:

#include <iostream>
using  std::cout;
using std::endl;


#ifndef BASE_H
#define BASE_H

template<typename T>
class Base
{
    public:
        Base();
        Base(T a0, T b0);
        void display();
    private:
        T a,b;
        T sum();
};

#endif // BASE_H

template<typename T>
Base<T>::Base():a(0),b(0){}

template<typename T>
Base<T>::Base(T a0, T b0):a(a0),b(b0){}

template<typename T>
T Base<T>::sum()
{
    return a+b;
}

template<typename T>
void Base<T>::display()
{
    cout<<"The sum is: "<<sum()<<endl;
}

我的 Derived.h 文件是:

#ifndef DERIVED_H
#define DERIVED_H

#include <Base.h>

template<typename T>
class Derived : public Base<T>
{
    public:
        Derived(){}
        Derived(T a0, T b0);
        void display1();
};

#endif // DERIVED_H

template<typename T>
Derived<T>::Derived(T a0, T b0):Base<T>(a0,b0) {}

template<T>
void Derived<T>::display1()
{

    this->display();
}

我知道模板类的实现不应该在.cpp文件中,但是为什么当我将单独的头文件放在不同的.h文件中时会出现未定义的错误?

报错如下(with code::blocks):

 ***include\Base.h|24|error: redefinition of 'Base<T>::Base()'|
 include\Base.h|24|error: 'Base<T>::Base()' previously declared here|*** 

最佳答案

两个问题。首先,您的 #include 守卫是错误的。你只是在守护类声明:

#ifndef BASE_H
#define BASE_H

template<typename T>
class Base
{
    ...
};

#endif // BASE_H

... definitions of Base<T> ...

如果 Base.h#included 两次,你只会得到一个类声明(好)但是你会得到所有成员的多个定义功能(坏)。

#include 守卫应该守卫整个 文件。将 #ifndef 移动到第一行,将 #endif 移动到最后一行。

第二个问题,如果你在头文件中提供你的成员函数定义但在类声明之外,你必须将函数标记为inline(这可以在声明或定义中完成,但我个人更喜欢声明)。即:

template <typename T>
class Base {
   ...
   inline Base();
   inline void display();
   inline T sum();
};

// definitions...

关于c++ - 为什么从基模板类继承并将两个类文件放在单独的头文件中时会出现重定义错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33016335/

相关文章:

c++ - operator[] 用于复杂度为 O(1) 的基于模板的数组

C++ - 通过模板类进行模板特化

c++ - 如何在编译时判断类是否包含某个成员函数

css - 为什么 CSS 类声明不适用于标记的 <div>?

c++ - 模板参数替换失败,C 字符串作为非类型模板参数

java - 从类方法显示进度对话框

c++ - 错误 c2259 'class' : cannot instantiate abstract class

c++ - 未定义的行为和顺序点

c++ - 如何创建辅助数据结构以在minheap中跟踪堆索引以进行C++中的reduce_key操作

c++ - 在 C++ 中为变量分配作用域