使用一个模板容器作为类的成员变量,如何不用在类的头文件中包含模板的头文件??

时间:2022-10-28 19:15:55
比如我现在一个类想用std::vector<int>作为成员变量,一般在这个类的头文件中就必须包含#include <vector>。但我现在在程序中使用了好几个不同的类库,模板定义包含在这个类的头文件中,这个类再被其它类使用时会有严重的定义冲突,根本不能编译(冲突好像在ATL和wxWidgets类库中)。

不知有什么办法可以不用在类的头文件中包含模板的定义,又可以在类中使用这个模板?当然可以不作为成员变量(如果有其它形式的话),但要能有成员变量的功能(作为类的状态的存储)。

比如如果要引用的是一个类的话(不是模板),那可以只定义指针,而在cpp中new出来,这样头文件中就不用包含要引用的类的定义

// 不需要在.h中包含#include "Class1.h"
class Class1;
class MyClass
{
  Class1 *class1_;
}

但模板好像又不能使用类似的方法(不能作为指针)。不知道还有没有办法可以使用模板类又不用在头文件中包含其定义??

谁能解决的话给100分。。。

8 个解决方案

#1


对了,或者谁要能解决定义冲突的问题的话也行。

我一个使用了ATL的类在一个wxWidgets类中编译时会出现定义出错,不是我的代码的问题,错误显示说某个系统类库的定义有错误(完全无助于找到实际错误的位置)。而且这种问题常常和几个类库的包含顺序有关
#include "1.h"
#include "2.h"
显示的错误和
#include "2.h"
#include "1.h"
显示的错误不一样。

应该就是在类库中的定义有冲突。但我不知具体冲突的位置,不知道有没有什么通用的办法能消除掉这种定义冲突?使用几个类库之间的定义不会互相影响?

#2


如同VC的预编译头设定一样,一般这种情况下我会把#include <vector>放在共用的都必须包含的头文件里面
然后把这个头文件放在各自的cpp文件包含的最前面,楼主可以试试

#3


把它移出头文件之外,例如:
//example.h
class Example
{
    struct Handle;
    Handle *handle;
    public:
        ...
    private:
        ...
};

//example.cc
#include <vector>
struct Example::Handle
{
        std::vector<int> vec;
        ...
};

#4


放在一个namespace里面如何?虽然不是解答楼主的问题,但我猜可以解决冲突的问题(没有验证):

namespace ATLNS {
#include ...
}

namespace WXNS {
#include ...
}

...

#5


真的是猜的……发觉应该不可行,因为库的实现文件没放在同样的namespace里面。sorry了楼主。

#6


引用 3 楼 fallening 的回复:
把它移出头文件之外,例如: 

C/C++ code//example.h
class Example
{
    struct Handle;
    Handle *handle;
    public:
        ...
    private:
        ...
};

//example.cc
#include <vector>
struct Example::Handle
{
        std::vector<int> vec;
        ...
};


有道理。想起有本书写过类似的方法。等我试试。

问题解决后给分。

#7


这个是否可行?
模板声明放在  a.h文件   定义放在      a.cpp  a.h后面#include"a.cpp"
或者
...........  a.h      ....        b.h    a.h后面#include"b.h"

#8


一样前置声明
namespace std
{
template<class ....> 
class vector;
};
这个参数要和你用的库的写法一致.

#1


对了,或者谁要能解决定义冲突的问题的话也行。

我一个使用了ATL的类在一个wxWidgets类中编译时会出现定义出错,不是我的代码的问题,错误显示说某个系统类库的定义有错误(完全无助于找到实际错误的位置)。而且这种问题常常和几个类库的包含顺序有关
#include "1.h"
#include "2.h"
显示的错误和
#include "2.h"
#include "1.h"
显示的错误不一样。

应该就是在类库中的定义有冲突。但我不知具体冲突的位置,不知道有没有什么通用的办法能消除掉这种定义冲突?使用几个类库之间的定义不会互相影响?

#2


如同VC的预编译头设定一样,一般这种情况下我会把#include <vector>放在共用的都必须包含的头文件里面
然后把这个头文件放在各自的cpp文件包含的最前面,楼主可以试试

#3


把它移出头文件之外,例如:
//example.h
class Example
{
    struct Handle;
    Handle *handle;
    public:
        ...
    private:
        ...
};

//example.cc
#include <vector>
struct Example::Handle
{
        std::vector<int> vec;
        ...
};

#4


放在一个namespace里面如何?虽然不是解答楼主的问题,但我猜可以解决冲突的问题(没有验证):

namespace ATLNS {
#include ...
}

namespace WXNS {
#include ...
}

...

#5


真的是猜的……发觉应该不可行,因为库的实现文件没放在同样的namespace里面。sorry了楼主。

#6


引用 3 楼 fallening 的回复:
把它移出头文件之外,例如: 

C/C++ code//example.h
class Example
{
    struct Handle;
    Handle *handle;
    public:
        ...
    private:
        ...
};

//example.cc
#include <vector>
struct Example::Handle
{
        std::vector<int> vec;
        ...
};


有道理。想起有本书写过类似的方法。等我试试。

问题解决后给分。

#7


这个是否可行?
模板声明放在  a.h文件   定义放在      a.cpp  a.h后面#include"a.cpp"
或者
...........  a.h      ....        b.h    a.h后面#include"b.h"

#8


一样前置声明
namespace std
{
template<class ....> 
class vector;
};
这个参数要和你用的库的写法一致.