C++ 模板类和派生类

C++ 模板类和派生类,c++,class,oop,templates,header-files,C++,Class,Oop,Templates,Header Files,我已经模板化了MyDatabase类和两个派生类Database\u A和Database\u B。我有另一个类C,它使用Database\u A和Database\u B。因此,每当我在类C中包含派生类(Database\u A和Database\u B)的头时,它都会给我这个错误“重新定义MyDatabase”。我的猜测是,因为派生类(Database\u A和Database\u B)都在拖动模板类MyDatabase,这可能是重新定义MyDatabase的原因。但我不知道如何解决这个问题

我已经模板化了
MyDatabase
类和两个派生类
Database\u A
Database\u B
。我有另一个类
C
,它使用
Database\u A
Database\u B
。因此,每当我在类
C
中包含派生类(
Database\u A
Database\u B
)的头时,它都会给我这个错误“重新定义
MyDatabase
”。我的猜测是,因为派生类(
Database\u A
Database\u B
)都在拖动模板类
MyDatabase
,这可能是重新定义
MyDatabase
的原因。但我不知道如何解决这个问题

我的代码:

 template <typename U, class T> class My_DataBase {
     protected:
     std::map<U,T> Container
     public:
     void add();
     T* getNameToPointer(string key);
 };

 class Database_A: public My_Database <string,A> {
     add();
     A* getNameToPointer(name);
 };

 class Database_B: public My_DataBase <string,B> {
     add();
     B* getNameToPointer(name);
 };

 class C {
     private:
     Database_A Db_A;    // drage template class on back_end
     Database_B Db_B;    // drage template class on back_end
 };
模板类My_数据库{
受保护的:
映射容器
公众:
无效添加();
T*getNameToPointer(字符串键);
};
类数据库\u A:公共我的\u数据库{
添加();
A*getNameToPointer(名称);
};
类数据库_B:公共My_数据库{
添加();
B*getNameToPointer(名称);
};
C类{
私人:
Database\u A Db\u A;//后端的drage模板类
Database_B Db_B;//后端的drage模板类
};

如何解决此问题?

您应该防止头文件被多次包含。 您可以通过在头文件顶部指定
#pragma once
指令来实现这一点(不过我认为这是特定于Microsoft的)。 更好的方法是使用类似于以下内容的代码围绕头文件:

#ifndef MYHEADER_FILENAME
#define MYHEADER_FILENAME
/// whatever contained in your header file
...
#endif // MYHEADER_FILENAME

看起来您有两个头文件,其中每个头文件包含基类和一个Derived类。这就是为什么会出现重新定义错误

要避免此问题,请执行以下操作:使用三个头文件并包含防护。基类将位于一个名为“My_DataBase.h”的头文件中。另外两个头文件(一个用于每个Derived类)将包括“My_DataBase.h”

然而,由于您可能希望包含(派生类的)两个头文件,所以需要使用include卫士来避免重新定义基类

下面是一个例子:

我的_数据库.h

#ifndef MY_DATABASE_H
#define MY_DATABASE_H
template <typename U, class T> class My_DataBase {
 protected:
 std::map<U,T> Container
 public:
 void add();
 T* getNameToPointer(string key);
}
#endif
\ifndef MY\u数据库\u H
#定义我的数据库
模板类My_数据库{
受保护的:
映射容器
公众:
无效添加();
T*getNameToPointer(字符串键);
}
#恩迪夫
数据库_A.h

#ifndef DATABASE_A_H
#define DATABASE_A_H

#include "My_DataBase.h"

class Database_A: public My_Database <string,A> {
 add();
 A* getNameToPointer(name);
}
\ifndef数据库
#定义数据库
#包括“My_DataBase.h”
类数据库\u A:公共我的\u数据库{
添加();
A*getNameToPointer(名称);
}
数据库_B.h

#ifndef DATABASE_B_H
#define DATABASE_B_H

#include "My_DataBase.h"

class Database_B:public My_DataBase <string,B> {
  add();
  B* getNameToPointer(name);
}
\ifndef数据库
#定义数据库
#包括“My_DataBase.h”
类数据库_B:公共My_数据库{
添加();
B*getNameToPointer(名称);
}

向我们展示一个完整的最小示例。这不是C,这是C++。简单的解释是,我有模板类A和两个派生类B和C。现在我有另一个类D,它使用两个类B& C。所以每当我在D中包含B& C的头文件时,它给了我对类A的重新定义的错误,那么如何避免这个问题???谢谢用标题文件更新你的问题。每当我使用B或C的标题文件时,它不会给出任何错误。但是一次包含两个头文件会导致重新定义模板类的错误。
#pragma once
在技术上是特定于编译器的,但实际上几乎适用于所有编译器,例如Visual Studio、GCC、Clang。