仅当类具有导出链接时"cannot access private member'"错误
"cannot access private member'" error only when class has export linkage
我最近不得不更改几个类的链接规范,遇到了一个问题。其中两个类包含一个值类型为std::unique_ptr
的std::map
。链接更改后,编译器开始抱怨"无法访问类std::unique_ptr<_Ty>'中声明的私有成员"错误。
有人知道为什么只有在提供了导出规范或有了解决方案时才会发生这种情况吗?
样本代码:
#include <map>
struct SomeInterface
{
virtual ~SomeInterface() = 0;
};
// This class compiles with no problems
struct LocalClass
{
std::map<int, std::unique_ptr<SomeInterface>> mData;
};
// This class fails to compile
struct __declspec(dllexport) ExportedClass
{
std::map<int, std::unique_ptr<SomeInterface>> mData;
};
编译器输出:
c:program files (x86)microsoft visual studio 10.0vcincludeutility(163): error C2248: 'std::unique_ptr<_Ty>::unique_ptr' : cannot access private member declared in class 'std::unique_ptr<_Ty>'
with
[
_Ty=SomeInterface
]
c:program files (x86)microsoft visual studio 10.0vcincludememory(2347) : see declaration of 'std::unique_ptr<_Ty>::unique_ptr'
with
[
_Ty=SomeInterface
]
c:program files (x86)microsoft visual studio 10.0vcincludeutility(195) : see reference to function template instantiation 'std::_Pair_base<_Ty1,_Ty2>::_Pair_base<const int&,_Ty2&>(_Other1,_Other2)' being compiled
with
[
_Ty1=const int,
_Ty2=std::unique_ptr<SomeInterface>,
_Other1=const int &,
_Other2=std::unique_ptr<SomeInterface> &
]
c:program files (x86)microsoft visual studio 10.0vcincludexmemory(208) : see reference to function template instantiation 'std::pair<_Ty1,_Ty2>::pair<const _Kty,_Ty>(std::pair<_Ty1,_Ty2> &)' being compiled
with
[
_Ty1=const int,
_Ty2=std::unique_ptr<SomeInterface>,
_Kty=int,
_Ty=std::unique_ptr<SomeInterface>
]
c:program files (x86)microsoft visual studio 10.0vcincludexmemory(280) : see reference to function template instantiation 'void std::allocator<_Ty>::construct<std::pair<_Ty1,_Ty2>&>(std::pair<_Ty1,_Ty2> *,_Other)' being compiled
with
[
_Ty=std::pair<const int,std::unique_ptr<SomeInterface>>,
_Ty1=const int,
_Ty2=std::unique_ptr<SomeInterface>,
_Other=std::pair<const int,std::unique_ptr<SomeInterface>> &
]
c:program files (x86)microsoft visual studio 10.0vcincludextree(592) : see reference to function template instantiation 'void std::_Cons_val<std::allocator<_Ty>,_Ty,std::pair<_Ty1,_Ty2>&>(_Alloc &,std::pair<_Ty1,_Ty2> *,std::pair<_Ty1,_Ty2>)' being compiled
with
[
_Ty=std::pair<const int,std::unique_ptr<SomeInterface>>,
_Ty1=const int,
_Ty2=std::unique_ptr<SomeInterface>,
_Alloc=std::allocator<std::pair<const int,std::unique_ptr<SomeInterface>>>
]
c:program files (x86)microsoft visual studio 10.0vcincludextree(1521) : see reference to function template instantiation 'std::_Tree_nod<_Traits>::_Node *std::_Tree_val<_Traits>::_Buynode<std::pair<_Ty1,_Ty2>&>(_Valty)' being compiled
with
[
_Traits=std::_Tmap_traits<int,std::unique_ptr<SomeInterface>,std::less<int>,std::allocator<std::pair<const int,std::unique_ptr<SomeInterface>>>,false>,
_Ty1=const int,
_Ty2=std::unique_ptr<SomeInterface>,
_Valty=std::pair<const int,std::unique_ptr<SomeInterface>> &
]
c:program files (x86)microsoft visual studio 10.0vcincludextree(1516) : while compiling class template member function 'std::_Tree_nod<_Traits>::_Node *std::_Tree<_Traits>::_Copy(std::_Tree_nod<_Traits>::_Node *,std::_Tree_nod<_Traits>::_Node *)'
with
[
_Traits=std::_Tmap_traits<int,std::unique_ptr<SomeInterface>,std::less<int>,std::allocator<std::pair<const int,std::unique_ptr<SomeInterface>>>,false>
]
c:program files (x86)microsoft visual studio 10.0vcincludemap(81) : see reference to class template instantiation 'std::_Tree<_Traits>' being compiled
with
[
_Traits=std::_Tmap_traits<int,std::unique_ptr<SomeInterface>,std::less<int>,std::allocator<std::pair<const int,std::unique_ptr<SomeInterface>>>,false>
]
c:projectssososo.cpp(18) : see reference to class template instantiation 'std::map<_Kty,_Ty>' being compiled
with
[
_Kty=int,
_Ty=std::unique_ptr<SomeInterface>
]
由于编译器无法为ExportedClass创建复制构造函数和复制赋值运算符,因此出现错误。这将需要复制没有复制构造函数的unique_ptr对象(它们是可移动的,但不可复制)。
对于普通类,没有给出错误,因为复制构造函数/赋值实际上没有在任何地方使用。然而,当__declspec(dllexport)出现时,所有编译器生成的函数都会被实例化(不确定这里的术语是否正确,但类似这样:)。
修复错误的一种方法是为ExportedClass定义这两个函数,并将它们标记为私有函数:
struct __declspec(dllexport) ExportedClass
{
std::map<int, std::unique_ptr<SomeInterface>> mData;
private:
ExportedClass(const ExportedClass&) {}
ExportedClass& operator=(const ExportedClass&) { return *this; }
};
我很久以前就遇到过这个问题,所以细节有点模糊。
本质上,当您导出一个类时,您还必须导出所有包含的类——公共或非公共。在您的情况下,这将是std::map
和std::unique_ptr
。我不确定标准库中的类在这里的表现,这是模糊的部分,但我记得我在这方面遇到过问题。
解决方案是导出这些类或使用PIMPL实现(无论如何,这对于导出的类来说都是个好主意)。
通常某个地方缺少"std::move(iUniquePtr)
"。
相关文章:
- std::make_shared和protected/private构造函数
- 将数组信息存储到 c++ 向量中有一个"Access violation reading location"
- 为什么调试器引发"read access violation. this was nullptr"异常?
- 在 Microsoft Access SQL 中调用自定义 DLL 函数时传递的内存地址无效
- 如何摆脱C++中未解析的外部符号"private: static char"错误?
- Simulink "Access Violation"写入 C++ lambda 函数捕获列表中的 PWork 变量
- C++ - "private"单身人士?
- Qt QXmlStreamReader Access Violation
- "Access is Denied" U盘上的创建文件()
- 将复制构造函数设置为private和=delete有什么区别
- 指向 std::unrodered_map 中元素的指针返回'Read access violation'
- 例外:'Access violation reading location'
- 向量数组"Cannot access memory at address"
- 库设计混乱.. "public"/"private"(模板)标题,库文件..?
- Windeployqt不会运行,"Access is denied."
- 我是否必须在类中的所有变量C++设置为 private?
- 将数据添加到 CArray 会产生错误"cannot access private member declared in class 'CObject'"
- 找到"cannot access private member declared in class 'QObject'"的根本原因
- 仅当类具有导出链接时"cannot access private member'"错误
- 一个函数,它是允许'read access'其'private members'但不能"写入访问权限"的'friend of a Class'?