小编RnR*_*RnR的帖子

从dll导出包含std :: objects(vector,map等)的类

我试图从包含std :: vectors和std :: strings等对象的DLL导出类 - 整个类通过以下方式声明为dll导出:

    class DLL_EXPORT FontManager
{
Run Code Online (Sandbox Code Playgroud)

问题是,对于复杂类型的成员,我收到此警告:

警告C4251:'FontManager :: m__fonts':类'std :: map <_Kty,_Ty>'需要让'FontManager'类的客户端使用dll接口[_Kty = std :: string,_Ty = tFontInfoRef ]

我可以通过在它们之前放置以下前向类声明来删除一些警告,即使我没有更改成员变量本身的类型:

template class DLL_EXPORT std::allocator<tCharGlyphProviderRef>;
template class DLL_EXPORT std::vector<tCharGlyphProviderRef,std::allocator<tCharGlyphProviderRef> >;
std::vector<tCharGlyphProviderRef> m_glyphProviders;
Run Code Online (Sandbox Code Playgroud)

看起来像前导声明"注入"DLL_EXPORT编译成员时,它是否安全?当客户端编译此标头并使用他身边的std容器时,它是否真的会改变任何东西?它是否会在将来使用这样的容器DLL_EXPORT(并且可能不是内联的?)?它是否真的解决了警告试图警告的问题?

这个警告是我应该担心的,还是最好在这些结构的范围内禁用它?客户端和dll将始终使用相同的库和编译器集构建,并且这些只是标题类...

我正在使用Visual Studio 2003和标准STD库.

----更新----

我想更多地针对你,因为我看到答案是一般性的,这里我们讨论的是std容器和类型(例如std :: string) - 也许问题确实是:

我们是否可以通过相同的库标题禁用客户端和dll可用的标准容器和类型的警告,并像处理int或任何其他内置类型一样处理它们?(它确实似乎在我身边正常工作.)如果可以,我们可以做到这一点的条件是什么?

或者应该禁止使用这样的容器,或者至少要特别小心,以确保没有赋值操作符,复制构造函数等内联到dll客户端?

一般来说,我想知道你是否觉得设计一个具有这些对象的dll接口(例如使用它们将东西作为返回值类型返回到客户端)是一个好主意或不是,为什么 - 我想要这个功能的"高级"接口......也许最好的解决方案是Neil Butterworth建议的 - 创建一个静态库?

c++ dll visual-studio

59
推荐指数
5
解决办法
5万
查看次数

你为什么要写这样的东西?(故意不在数组上使用delete [])

我曾偶尔遇到过这种代码 - 我怀疑创建者是/害怕表删除会迭代表和"性价比"(imho不会以任何方式完成)......有没有真正的从不使用表删除这里可能得到/考虑/想象的好处?

myClass** table = new myClass* [size];
... //some code that does not reallocate or change the value of the table pointer ;)
delete table; // no [] intentionally
Run Code Online (Sandbox Code Playgroud)

c++ coding-style

7
推荐指数
5
解决办法
1521
查看次数

如何以可维护的方式为整个类层次结构保护析构函数?

我想确保没有人能够从我的类层次结构中删除任何对象,然后使用提供的Destroy方法.

基本原理是来自此层次结构的任何对象在开始销毁自身之前需要使用特殊的写入互斥锁,以确保在另一个线程使用它们时不会删除对象.

我知道我可以通过引用计数来防止这个问题,但对于潜在的性能影响和内存分配而言,这对系统来说将是一个更大的变化.

有没有办法以某种方式有效/巧妙地使所有的析构函数受到保护,以便子类可以调用他们的父母析构函数,而外人必须使用Destroy?

我提出的一个安全(即它不会腐烂)的解决方案是将所有析构函数设为私有并将每个派生类声明为基类的朋友,但我更喜欢更优雅,更少手动和更容易的东西维护(不需要修改基类以便从中派生).

有这样的东西吗?也许一些聪明的伎俩会让事情像我一样"有效"?

PS.我现在选择的解决方案是不阻止任何人在所有情况下调用delete(只是在基类中保护它)但检测到这种情况并在基类析构函数中调用abort.

c++ destructor code-structure

5
推荐指数
1
解决办法
164
查看次数