我正在阅读网站 The C ++ Programming Language 中C++ Super-FAQ中构造函数初始化的顺序。在那里提供以下代码。
#include <iostream>
class Y {
public:
Y();
void f();
};
Y::Y() { std::cout << "Initializing Y\n"; }
void Y::f() { std::cout << "Using Y\n"; }
class X {
public:
X(Y& y);
};
X::X(Y& y) { y.f(); }
class Z {
public:
Z();
protected:
X x_;
Y y_;
};
Z::Z()
: y_()
, x_(y_)
{ }
int main()
{
Z z;
return 0;
}
此代码的打印序列为:
使用Y
初始化Y
好吧,我只是无法意识到这个打印序列是如何可能的,因为在Z类的构造函数中,Y类的实例 y _ 首先被实例化,然后实例 x _ Y :: f(),如何使用与所使用的方法顺序密切相关的打印订单怎么样?我需要实现一个Y,它可以称之为构造函数和打印例程 std :: cout&lt;&lt; “初始化Y \ n”; 。
答案 0 :(得分:4)
自X x_
Y y_
class Z
x_
之前Z::Z() : y_(), x_(y_) {}
之后,y_
定义class Z {
public:
Z();
protected:
Y y_;
X x_;
};
并首先进行初始化。将成员放置在初始化列表x_
中的顺序并不重要,x_仍然是首先初始化。
由于y_
的构造函数未被调用,因此某些内部元素(例如vtable)已经初始化。实际上在X&#39的构造函数中使用此对象可能会导致段错误。也许这种定义对你来说会更好。
y_
在x_
之后定义Y* p = 0;
X x(reinterpret_cast<Y&>(p));
,首先会调用 func showDropIn(clientTokenOrTokenizationKey: String) {
let request = BTDropInRequest()
let dropIn = BTDropInController(authorization: clientTokenOrTokenizationKey, request: request)
{ (controller, result, error) in
if (error != nil) {
print("ERROR")
} else if (result?.cancelled == true) {
print("CANCELLED")
} else if result != nil {
// Use the BTDropInResult properties to update your UI
// result.paymentOptionType
// result.paymentMethod
// result.paymentIcon
// result.paymentDescription
}
dispatch_async(dispatch_get_main_queue(), ^{
controller.dismissViewControllerAnimated(true, completion: nil)
});
}
dispatch_async(dispatch_get_main_queue(), ^{
self.presentViewController(dropIn!, animated: true, completion: nil)
});
}
,您可以在ng2-page-scroll
的构造函数中安全地使用它。
您可能希望阅读本文的Initialization order部分。
编辑: C ++值加速并信任程序员,因此它不会尝试验证给定的参数。您可以将空指针强制转换为引用,然后使用引用。
onClickkk() {
if(this.document.location.href.indexOf('resor') !== -1 ) {
let pageScrollInstance: PageScrollInstance = PageScrollInstance.simpleInstance(this.document, '#app-give');
this.pageScrollService.start(pageScrollInstance);
}
}
这将编译,如果编译器不需要延迟我们的空指针,它将不会失败。如果您创建虚拟或尝试访问任何成员,则会导致段错误。
答案 1 :(得分:2)
您的班级Z
按此顺序声明两名成员:
X x_;
Y y_;
但是,它们按相反的顺序初始化:
Z::Z()
: y_()
, x_(y_)
{ }
你需要小心这个,例如请参阅this question或this
更改声明和初始化的顺序以匹配您期望的内容。你有未定义的行为,一些编译会警告你关于oder的不匹配。
您已关联的特定psot在评论中显示"// Bad: should have listed x_ before y_"
并提取要点
注意在初始化之前使用y_(Y :: f())(Y :: Y())。