如何解决从成员初始化程序列表中调用基本方法
从成员初始化程序列表中调用非虚拟基本方法是否安全?和虚拟的?
解决方法
在初始化所有基础之前,调用任何成员函数(虚拟或非虚拟)都不安全。以下是标准([class.base.init]§16)中给出的示例:
class A {
public:
A(int);
};
class B : public A {
int j;
public:
int f();
B() : A(f()),// undefined behavior: calls member function but base A not yet initialized
j(f()) { } // well-defined: bases are all initialized
};
class C {
public:
C(int);
};
class D : public B,C {
int i;
public:
D() : C(f()),// undefined behavior: calls member function but base C not yet initialized
i(f()) { } // well-defined: bases are all initialized
};
还有更多subtle cases。
,正如我在评论中所说的:
在派生类的初始化程序列表中初始化的第一件事是基类。明确地看起来像这样:
class A{ ... };
class B : public A {
int x,y;
B() : A{},x{...},y{...} {
...
}
};
因此,在初始化x
和y
时,您可以调用A
的任何非虚拟方法,因为它已经构造。
问题的第二部分与virtual
ness并没有多大关系,它只是一个问题,即是否可以在构造函数中调用成员函数。答案是是,但是-您需要确保不使用对象的任何未初始化部分。
例如
struct Base {
virtual int f(int i) = 0;
};
struct Derived : public Base {
int x;
int y;
virtual int f(int i) override { return i; }
Derived(int i) : Base{},x{f(i)},y{f(x)} {}
};
很好,但是写... Derived(int i) : Base{},x{f(y)},y{f(i)} ...
不好。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。