gpt4 book ai didi

c++ - 在 dll 接口(interface)中使用 STL 类时消除 C4251 警告的一种方法

转载 作者:IT老高 更新时间:2023-10-28 21:55:01 26 4
gpt4 key购买 nike

在 dll 接口(interface)中使用 STL 类作为 Common practice in dealing with warning c4251: class … needs to have dll-interface 不是一个好习惯。解释。举个例子:

#include <iostream>
#include <string>
#include <vector>


class __declspec(dllexport) HelloWorld
{
public:
HelloWorld()
{
abc.resize(5);
for(int i=0; i<5; i++)
abc[i] = i*10;

str="hello the world";
}
~HelloWorld()
{

}

std::vector<int> abc;
std::string str;

};

编译此文件时,可以观察到以下警告:

 warning C4251: 'HelloWorld::str' : class 'std::basic_string<_Elem,_Traits,_Ax>' needs to have dll-interface to be used by clients of class 'HelloWorld'    
warning C4251: 'HelloWorld::abc' : class 'std::vector<_Ty>' needs to have dll-interface to be used by clients of class 'HelloWorld'

那么问题是我们如何在不使用 STL 类 vector 和字符串的情况下实现相同的功能。我能想到的一种实现如下:

class __declspec(dllexport) HelloWorld2
{
public:
HelloWorld2()
{
abc_len = 5;
p_abc = new int [abc_len];
for(int i=0; i<abc_len; i++)
p_abc[i] = i*10;

std::string temp_str("hello_the_world");
str_len = temp_str.size();
p_str = new char[str_len+1];
strcpy(p_str,temp_str.c_str());
}
~HelloWorld2()
{
delete []p_abc;
delete []p_str;
}

int *p_abc;
int abc_len;
char *p_str;
int str_len;



};

如您所见,在新的实现中,我们使用 int *p_abc 替换 vector abc 和 char *p_str 替换字符串 str。我的问题是是否有其他优雅的实现方法可以做到这一点。谢谢!

最佳答案

我认为您至少有 5 种可能的选择来解决这个问题:

  1. 您仍然可以为您的字段保留 STL/模板类,并将它们用作参数类型,只要您将所有字段保密(无论如何这是一个好习惯)。 Here是关于这个的讨论。要删除警告,您可以简单地使用 #pragma 语句。

  2. 您可以创建带有私有(private) STL 字段的小型包装类,并将包装类类型的字段公开给公众,但这很可能只会将警告移到其他地方。

  3. 您可以使用 PIMPL将您的 STL 字段隐藏在私有(private)实现类中的习惯用法,它甚至不会从您的库中导出,也不会在其外部可见。

  4. 或者您可以按照 here 中描述的方式实际导出所有必需的模板类特化,如 C4251 警告中所建议的那样。 .简而言之,您必须在 HelloWorld 类之前插入以下代码行:

    ...
    #include <vector>

    template class __declspec(dllexport) std::allocator<int>;
    template class __declspec(dllexport) std::vector<int>;
    template class __declspec(dllexport) std::string;

    class __declspec(dllexport) HelloWorld
    ...

    顺便说一句,这些导出的顺序似乎很重要: vector 类模板在内部使用分配器类模板,因此分配器实例化必须在 vector 实例化之前导出。 p>

  5. 直接使用内在函数可能是你最糟糕的选择,但如果你封装你的字段

    int *p_abc;
    int abc_len;

    class MyFancyDataArray 和字段中

    char *p_str;
    int str_len;

    class MyFancyString 之类的东西中,那么这将是一个更体面的解决方案(类似于第二点描述的解决方案)。但过于频繁地重新发明轮子可能不是最好的习惯。

关于c++ - 在 dll 接口(interface)中使用 STL 类时消除 C4251 警告的一种方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16419318/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com