编辑:立即编译代码。还添加了更详细的代码来描述确切的场景。
在初始值设定项列表中传递此指针安全吗?在构建对象之前调用对象方法的情况下,是否存在分割错误的可能性?或者在构造函数中传递这个指针更好?以下是示例类。
#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
的Initializer列表非常大,并且在其完全执行之前,触发事件(为此注册了第三个类),并且该事件调用ThirdClass
的someMethod()
。这样做会导致未定义的行为。或者根本不存在未定义行为的可能性?
PS:这里也有类似的问题,使用";这个";初始化列表中的指针?但其中提到了一些亲子关系。
如果ThirdClass
的构造函数中的first
变量未被使用,仅存储以供将来使用,则这是安全且定义良好的。如果您试图在构造函数中使用/取消引用指针,那么这将是未定义的行为,因为FirstClass
对象尚未构造。
在您的示例中,您写道:
在此处注册一些事件。
在执行FirstClass的初始值设定项列表之前,事件将调用someMethod,而someMethod正在调用FirstClass方法。
因为这意味着将调用对象的方法,所以这可能是无效的,并且将是Undefined Behavior,因为您不能调用未初始化对象的方法(除非函数所依赖的所有成员都已初始化)。