在 C++ 的初始化列表中传递这个指针是否安全?
Is it safe to pass this pointer in the initializer list in C++?
编辑: 正在编译代码。还添加了更详细的代码来描述确切的场景。
在初始化列表中传递这个指针安全吗?如果在构造对象之前调用对象方法,是否有可能出现分段错误?或者更好地在构造函数中传递这个指针?以下是示例 classes.
#include "iostream"
using namespace std;
class Observer
{
public:
Observer() = default;
protected:
Observer(const Observer& other) = default;
Observer(Observer&& other) = default;
Observer& operator=(const Observer& other) = default;
Observer& operator=(Observer&& other) = default;
public:
virtual ~Observer() = default;
virtual void method() const
{
}
};
class ThirdClass
{
public:
ThirdClass(const Observer* const first) : firstPtr{first}
{
// register for some events here.
// that events will call someMethod and someMethod is calling FirstClass's method, before initializer list of FirstClass gets executed.
}
void someMethod()
{
firstPtr->method();
}
static ThirdClass& getInstance(const Observer* const first)
{
static ThirdClass instance = ThirdClass(first);
return instance;
}
private:
const Observer* firstPtr{};
};
class FirstClass: public Observer
{
public:
FirstClass():third(ThirdClass::getInstance(this))
// init
// init
// some big initializer list which will take time to inilialize
{
}
virtual void method() const override
{
}
private:
const ThirdClass& third;
};
int main()
{
FirstClass firstObj;
return 0;
}
假设这样的场景,FirstClass
的初始化列表非常大,在它完全执行之前,事件被触发(为此,第三个 class 被注册)并且该事件调用 [= ThirdClass
的 12=]。这是否会导致未定义的行为。或者根本没有未定义行为的机会?
PS:这里也有类似的问题Is it safe to use the "this" pointer in an initialization list?但是提到了一些亲子关系。
如果 first
变量,在 ThirdClass
的构造函数中 没有 使用,只存储以备将来使用,那么这是安全且定义明确的.如果您尝试 use/dereference 构造函数中的指针,那么这将是未定义的行为,因为尚未构造 FirstClass
对象。
在您的示例中,您写道:
register for some events here.
that events will call someMethod and someMethod is calling FirstClass's method, before initializer list of FirstClass gets executed.
既然这意味着将调用对象的方法,那么这可能是无效的,并且将是未定义的行为,因为您不能调用未初始化对象的方法(除非该函数依赖的所有成员都已初始化)。
编辑: 正在编译代码。还添加了更详细的代码来描述确切的场景。
在初始化列表中传递这个指针安全吗?如果在构造对象之前调用对象方法,是否有可能出现分段错误?或者更好地在构造函数中传递这个指针?以下是示例 classes.
#include "iostream"
using namespace std;
class Observer
{
public:
Observer() = default;
protected:
Observer(const Observer& other) = default;
Observer(Observer&& other) = default;
Observer& operator=(const Observer& other) = default;
Observer& operator=(Observer&& other) = default;
public:
virtual ~Observer() = default;
virtual void method() const
{
}
};
class ThirdClass
{
public:
ThirdClass(const Observer* const first) : firstPtr{first}
{
// register for some events here.
// that events will call someMethod and someMethod is calling FirstClass's method, before initializer list of FirstClass gets executed.
}
void someMethod()
{
firstPtr->method();
}
static ThirdClass& getInstance(const Observer* const first)
{
static ThirdClass instance = ThirdClass(first);
return instance;
}
private:
const Observer* firstPtr{};
};
class FirstClass: public Observer
{
public:
FirstClass():third(ThirdClass::getInstance(this))
// init
// init
// some big initializer list which will take time to inilialize
{
}
virtual void method() const override
{
}
private:
const ThirdClass& third;
};
int main()
{
FirstClass firstObj;
return 0;
}
假设这样的场景,FirstClass
的初始化列表非常大,在它完全执行之前,事件被触发(为此,第三个 class 被注册)并且该事件调用 [= ThirdClass
的 12=]。这是否会导致未定义的行为。或者根本没有未定义行为的机会?
PS:这里也有类似的问题Is it safe to use the "this" pointer in an initialization list?但是提到了一些亲子关系。
如果 first
变量,在 ThirdClass
的构造函数中 没有 使用,只存储以备将来使用,那么这是安全且定义明确的.如果您尝试 use/dereference 构造函数中的指针,那么这将是未定义的行为,因为尚未构造 FirstClass
对象。
在您的示例中,您写道:
register for some events here.
that events will call someMethod and someMethod is calling FirstClass's method, before initializer list of FirstClass gets executed.
既然这意味着将调用对象的方法,那么这可能是无效的,并且将是未定义的行为,因为您不能调用未初始化对象的方法(除非该函数依赖的所有成员都已初始化)。