Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/159.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何在stl模板中使用导出的类(uu declspec(dllexport))?_C++_Templates_Dllexport - Fatal编程技术网

C++ 如何在stl模板中使用导出的类(uu declspec(dllexport))?

C++ 如何在stl模板中使用导出的类(uu declspec(dllexport))?,c++,templates,dllexport,C++,Templates,Dllexport,我使用的是导出类 class __declspec(dllexport) myclass { private: template __declspec(dllexport) class std::map<myclass*,int>; std::map<myclass*,int>m_map; //something }; class\uuu declspec(dllexport)myclass { 私人: 模板declspec(dl

我使用的是导出类

class __declspec(dllexport) myclass  
{  
private:  
template __declspec(dllexport) class std::map<myclass*,int>;    
std::map<myclass*,int>m_map;  
//something  
};    
class\uuu declspec(dllexport)myclass
{  
私人:
模板declspec(dllexport)类std::map;
std::mapm_图;
//某物
};    
当我这样做时,我得到一个警告C4251,说m_map:类'std::map'需要有dll接口才能被类myclass的客户端使用。
关于如何解决这个问题,有什么想法吗?

Atul

不能导出包含未导出成员的类。一个可能的解决方案是使用Pimpl习惯用法。使用Pimpl,用户不知道类的成员。因此,不需要导出stl类。有关pimpl的更多信息,请查看以下内容: 或

例如:

myclass.h:

class __declspec(dllexport) myclass
{
public:
    myclass();
    virtual ~myclass();
private:
    myclass(const myclass& other) {}
    myclass& operator=(const myclass& rhs) {return *this;}
    myclassImpl* m_Pimpl;
};
myclass.cpp:

#include "myclass.h"
#include "myclassImpl.h"


myclass::myclass()
    :m_Pimpl(new myclassImpl())
{}

myclass::~myclass() {
    delete m_Pimpl;
}
myclassImpl.h:

class myclassImpl {
private:
    std::map<myclass*,int>m_map;
};
类myclassImpl{
私人:
std::mapm_图;
};

您不应该在使用DLL的代码将要使用的头文件中使用u declspec(dllexport),因为它们需要使用u declspec(dllimport)

因此,如果设置了特定的其他定义,则应创建使用dllexport的宏,如果未设置,则应创建使用dllimport的宏

在某个公共标题中:

#ifdef EXPORTING_FOO
#define FOO_API __declspec(dllexport)
#else
#define FOO_API __declspec(dllimport)
#endif
您可以实例化一个模板:

extern template class FOO_API Templ<MyClass, int >;
extern模板类FOO_API模板;
在包含的标题中。注意这里的外部。 在一个编译单元内声明相同但没有外部和FOO_API,因此:

template class Templ<MyClass, int >;
模板类模板;
这意味着使用库的代码不会实例化模板,而是使用库中的模板。当模板具有虚拟成员时,这尤其有用

如果模板来自标准库或boost,则使用您的代码的版本必须与您的版本相同,否则可能会出现严重问题


在您自己的示例中,它出现在私有区域,这表明您希望从库的接口中重构它。理想情况下,库应该只公开公共方法和成员,而不是转发声明。为了使类不可复制和不可分配,可以使用私有复制构造函数和赋值-它们实际上不是实现的一部分,它们是类接口的一部分(您是说您不能复制或赋值)。

@David,你能详细说明一下这个Pimpl习惯用法吗?很好,但是你让析构函数虚拟化会给你自己带来更多的问题。没有人会从它们中派生出来,因为如果你想要多态性,你就把它放到pImpl中。您还应该使您的类不可复制和不可分配。@CashCow您是对的-代码没有适当注意分配和复制。但它可以被库的用户继承。这就是我在2010年时的做法,但现在实际上我有一个stdafx.h文件或类似文件,它包含在所有项目源中,但不包含在外部用户源中,它定义了FOO_API或任何东西。然后,标头只执行#ifndef FOO#u API,还将执行#pragma命令库。