我在书中看到了这段代码"C++高性能";Bjorn Andrist和Viktor Sehr。代码示例实际上用于表明";尽管函数已声明为const
,但仍进行编译&";,我知道这一点。然而,在此之前,我还没有见过int* ptr_{};
和Foo(int* ptr):ptr_{ptr}{}
。这两段代码在做什么,特别是Foo(int* ptr):ptr_{ptr}{}
?作为示例使用的整个代码片段如下:
class Foo {
public:
Foo(int* ptr):ptr_{ptr}{}
auto set_ptr_val(int v) const {
*ptr_ = v; // Compiles despite function being declared const!
}
private:
int* ptr_{};
};
int main(){
auto i = 0;
const auto foo = Foo{&i};
foo.set_ptr_val(42);
}
Foo(int* ptr) : ptr_{ptr}{}
- 声明并定义类CCD_ 5的构造函数
- 其接收输入CCD_ 6(指向CCD_
- 并通过成员初始化器列表初始化成员变量CCD_ 8
- 它什么也不做,所以身体是emtpy,
{}
int* ptr_{};
使用一种可能的值初始化语法对CCD_ 10进行零初始化;由于它的类型是int*
,所以它将与nullptr
进行初始化,因此这相当于int* ptr_{nullptr};
。
关于他们提出的观点,我认为他们过度强调了正常观察,从而使其看起来像一条特殊规则:
- 类有一个名为
ptr_
的成员,它是int*
,即指向int
的指针 - 成员函数
set_ptr_val
是const
,因此它承诺不会更改ptr_
或任何其他(非mutable
)成员 - 事实上,
set_ptr_val
的主体并没有修改ptr_
;它修改的是指向CCD_ 23。但没关系
让我们从简单的一个开始:int* ptr_{};
。这只是定义了一个名为ptr_
的成员变量,它是指向int
的指针。{}
只是将其初始化为null。
下一个是Foo(int* ptr):ptr_{ptr}{}
。如果我们以不同的方式格式化,就会更清楚地了解发生了什么:
Foo(int* ptr)
: ptr_{ptr}
{
}
这是一个构造函数,类名Foo
的使用证明了这一点。它只需要一个参数(这使得能够在main()
内部使用Foo{&i}
)。从那里开始,冒号(:
)开始一个成员初始值设定项列表,在这里可以初始化成员变量。通常,这可以是成员初始值设定项的逗号分隔列表。代码ptr_{ptr}
就是这样一个成员初始化器,它将成员变量ptr_
初始化为具有与参数ptr
相同的值。即ptr_
将指向与ptr
相同的int
。最后,我们有了构造函数主体,在本例中它是空的,因此除了大括号之外什么都不包含。