最近我偶然发现了this关于如何在现代 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-initialization 自 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
- 列表初始化阻止您使用 most-vexing parse :
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
};
关于c++ - 使用大括号实例化 - 它是什么以及为什么在这里使用它?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57411115/