微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

从成员初始化程序列表中调用基本方法

如何解决从成员初始化程序列表中调用基本方法

从成员初始化程序列表中调用非虚拟基本方法是否安全?和虚拟的?

解决方法

在初始化所有基础之前,调用任何成员函数(虚拟或非虚拟)都不安全。以下是标准([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{...} {
        ...
    }
};

因此,在初始化xy时,您可以调用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 举报,一经查实,本站将立刻删除。