【发布时间】:2020-07-22 13:11:26
【问题描述】:
我有两个文件:
Header.h
#pragma once
#ifdef UNIQUEPTRISSUE_EXPORTS
#define UNIQUEPTRISSUE_API __declspec(dllexport)
#else
#define UNIQUEPTRISSUE_API __declspec(dllimport)
#endif
UniquePtrIssue.cpp
#include "stdafx.h"
#include "Header.h"
#include <memory>
#include <vector>
class UNIQUEPTRISSUE_API ClassA {
};
class UNIQUEPTRISSUE_API ClassB {
private:
std::vector<std::unique_ptr<ClassA>> x;
};
编译会引发以下错误:
1>d:\program files (x86)\microsoft visual 工作室\2017\企业\vc\tools\msvc\14.14.26428\include\xutility(2443): 错误 C2280: 'std::unique_ptr> &std::unique_ptr<_ty>>::operator =(const std::unique_ptr<_ty>> &)':试图 引用已删除的函数 1> 与 1> [ 1> _Ty=A 类 1>]
访问unique_ptr 的复制构造函数时似乎会出现类似的问题,但它们似乎并不适用。
从两个类声明中删除 UNIQUEPTRISSUE_API/__declspec(dllexport) 似乎会使错误消失。
显然,__declspec(dllexport) 声明发生了一些我不明白的事情。有什么方法可以在导出的类之间使用unique_ptrs?
【问题讨论】:
-
为什么要从 DLL 中导出类?这是高度依赖于编译器的。即使您可以无错误地导出,您也无法在其他编译器中使用您的类,尤其是当它依赖于 STL 类时,因为 DLL 用户可能没有使用与您的 DLL 相同的 STL 实现。您应该努力避免在 DLL 边界上使用非 POD 数据。
-
感谢@RemyLebeau 我不太担心编译器依赖性,因为这是我只希望自己使用的个人项目。我首先导出类的原因是因为我打算让客户能够对它们进行子类化。还有其他方法可以在 DLL 边界上提供多态性和继承吗?
-
即使您自己使用它,总有一天您可能需要更新您的编译器,这将需要重新编译 DLL 以匹配。多态性在 DLL 边界上并不能很好地工作,并且继承最好限制在 DLL 仅公开对抽象接口的访问(就像 COM 所做的那样)。
-
奇怪的是,我无法重现 rextester.com 上的错误...
标签: c++ stl c++14 c++17 dllexport