如何将 unique_ptr 对象作为参数传递给作为库的类
Posted
技术标签:
【中文标题】如何将 unique_ptr 对象作为参数传递给作为库的类【英文标题】:How to pass unique_ptr object as argument to a class that is a library 【发布时间】:2018-03-24 19:57:09 【问题描述】:我阅读了与将 unique_ptr 作为参数传递给类构造函数相关的所有问题和答案,这些答案适用于 exe 中的类。但是在这里我试图将一个 unique_ptr 对象传递给一个预编译为静态库的类构造函数。
库中的这个类看起来是这样的,
// Class declaration (in a header file)
class TScreen
private:
std::unique_ptr<TProcess> m_process;
public:
__fastcall TScreen(int a, std::unique_ptr<TProcess> i_process);
;
// The constructor definition (in a separate .cpp file)
__fastcall TScreen::TScreen(int a, std::unique_ptr<TProcess> i_process):
m_process(std::move(i_process))
我将尝试像这样在 exe 中实例化 TScreen 类,
void TScreen_Main::CallScreen()
std::unique_ptr<TProcess> objprocess (new TProcess());
std::unique_ptr<TScreen> objscreen (new TScreen(0, std::move(objprocess)));
我编译了库并将其导入到 exe 中。当我编译exe时,它给了我一个这样的链接错误,
[ilink32 Error] Error: Unresolved external '__fastcall TScreen::TScreen(int, std::unique_ptr<TProcess, std::default_delete<TProcess> >)' referenced from TSCREEN_MAIN.OBJ
[ilink32 Error] Error: Unable to perform link
我也对 boost::shared_ptr 进行了同样的尝试,但它给了我同样的错误。但它适用于原始指针,但不适用于智能指针,我不知道为什么?
提前致谢。
【问题讨论】:
尝试将inline
放在__fastcall
之后。这是一个链接问题。所以,不知何故,这个函数永远不会把它变成一个 obj 文件。即使它可能永远不需要,因为它很容易内联。如果您明确声明它inline
,这会告诉链接器,如果它确实需要定义它需要在任何地方发出它,那么该定义将不仅仅是位于某个随机的.obj
文件中。
【参考方案1】:
您的问题是链接问题。现在,我很难说到底发生了什么,因为我从来没有在 Windows 环境中工作过,而链接(虽然非常相似)在 Unix/Linux 和 Windows 环境之间有一些明显的区别。
我的猜测是,如果你明确声明你的构造函数为inline
,并声明定义为inline
,它就会正常工作。
这假设您将类的声明和定义放在一起表明定义与类一起在头文件中。
当编译器看到它被声明为inline
时,它会在需要它的每个编译单元中发出一个定义。然后链接器应该消除所有重复的定义。
如果您确实在某个 .cpp
文件中定义构造函数,该文件与该类所在的 .hpp
文件分开,并且您将 .cpp
文件编译为 .obj
文件,最终将其编译为 @987654328 @ 或 .dll
在创建可执行文件时链接,那么我不知道问题是什么。如果是这种情况,您应该使用开发环境附带的工具来查看库或 dll 中实际存在哪些符号,因为构造函数定义的符号不存在。
【讨论】:
谢谢你,你的回答让我知道我在找什么。我的构造函数定义在单独的.cpp
中,所以我要查找的关键字不是inline
。我必须声明构造函数explicit
,现在链接发生了。
@RaviSangar - 这不应该有任何影响。 explicit
与链接或符号可见性无关。它只告诉编译器构造函数不能用于隐式转换,这对于多参数构造函数来说是毫无意义的,因为无论如何它们永远不会(AFAIK)被考虑用于隐式转换。我的猜测是您修改 .cpp
文件会迫使您的 IDE 重新编译并重新生成您的库。
实际上,作为提高代码质量的编码指南,我们声明所有类构造函数explicit
,所以我想在尝试您的建议之前添加它并且它有效。我还尝试在同一个文件中添加带有 inline
关键字的声明和定义,这也很有效。以上是关于如何将 unique_ptr 对象作为参数传递给作为库的类的主要内容,如果未能解决你的问题,请参考以下文章
如何通过 HtmlDocument.InvokeScript 将对象作为参数传递给 javascript