最近我偶然发现了这篇关于如何在现代C++中导入dll库的文章。代码完全让我不知所措,所以我一行一行地浏览它并试图弄清楚它的含义。到目前为止,我想我明白了,但有一件事我仍然不清楚:
class ShellApi {
DllHelper _dll{"Shell32.dll"};
/* ... */
};
class DllHelper {
public:
explicit DllHelper(LPCTSTR filename) : _module(LoadLibrary(filename)) {}
/* ... */
private:
HMODULE _module;
};
为什么实例化DllHelper _dll{"Shell32.dll"}
用大括号而不是普通括号编写?我在Visual Studio中尝试了一下,不得不意识到这个片段不适用于普通括号。为什么不呢?这种实例化是如何调用的(以便我稍后可以查找(?是否还有其他使用此功能的方案?
如果我提供的代码不足以回答问题,则整个代码可在文章中找到。
List初始化自C++11以来就存在,通常被视为当今初始化对象的实际方式(除了一些特殊情况(:
std::string s{"foo"}; // Initialize the std::string s with "foo"
列表初始化和直接初始化之间存在差异,这些差异在 https://en.cppreference.com/w/cpp/language/list_initialization 上进行了总结,其中一些是:
- 列表初始化不允许缩小转换范围:
int f();
char c1(f()); // Ok
char c2{f()}; // error: narrowing conversion from int to char
- 列表初始化可防止您进行最烦人的解析:
struct X { };
X x1(X()); // x1 is a function
X x2{X{}}; // x2 is a X
- 在您的情况下,列表初始化用于默认初始化
ShellApi
的非静态成员,并且您不能使用()
来初始化它:
struct X {
int a1{1}; // Ok
int a2 = 1; // Ok
int a3(1); // Nok
int b{}; // Ok, b is an int member default-initialized to 0
int b(); // Ok, b is a member-function returning an int
};