Ali*_*401 3 c++ stl dllexport c++14 c++17
我有两个文件:
头文件.h
#pragma once
#ifdef UNIQUEPTRISSUE_EXPORTS
#define UNIQUEPTRISSUE_API __declspec(dllexport)
#else
#define UNIQUEPTRISSUE_API __declspec(dllimport)
#endif
Run Code Online (Sandbox Code Playgroud)
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;
};
Run Code Online (Sandbox Code Playgroud)
编译会引发以下错误:
1>d:\program files (x86)\microsoft visual studio\2017\enterprise\vc\tools\msvc\14.14.26428\include\xutility(2443): error C2280: 'std::unique_ptr> &std::unique_ptr< _Ty,std::default_delete<_Ty>>::operator =(const std::unique_ptr<_Ty,std::default_delete<_Ty>> &)': 试图用 1> [ 1> _Ty 引用已删除的函数 1> =A级1>]
访问 a 的复制构造函数时似乎会出现类似的问题,unique_ptr但它们似乎并不适用。
从两个类声明中删除UNIQUEPTRISSUE_API/__declspec(dllexport)似乎会使错误消失。
显然,__declspec(dllexport)声明中发生了一些我不明白的事情。有什么办法可以unique_ptr在导出的类之间使用s 吗?
当您使用 声明一个类时declspec(dllexport),编译器必须生成该类的所有成员函数,包括默认构造函数、复制赋值等函数,因为它不知道导入模块可能需要哪些函数。在 C++ 类中使用 dllimport 和 dllexport 中对此进行了描述。
由于 aunique_ptr不能被复制,它的复制构造函数和复制赋值运算符被删除,当向量对象试图使用它们时,你会得到C2280错误。
不包含时declspec(dllexport),编译器只会生成实际使用的函数,避免了有问题的副本。
解决此问题的一种方法是导出单个类成员函数,这可能意味着将其中一些指定为默认值。 virtual函数不需要导出,因为它们是由 vtable 处理的。
另一种解决方法是显式删除复制构造函数和复制赋值运算符。由于这将阻止创建默认构造函数并移动构造函数/赋值函数,因此您可能需要将它们默认设置。
class UNIQUEPTRISSUE_API ClassB {
public:
ClassB(const ClassB &) = delete;
ClassB &operator=(const ClassB &) = delete;
// You may need to explicitly default these if they are used
ClassB() = default;
ClassB &operator=(ClassB &&) = default;
ClassB(ClassB &&) = default;
private:
std::vector<std::unique_ptr<ClassA>> x;
};
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
945 次 |
| 最近记录: |