为什么成员分配在初始化列表中失败但在构造函数中却没有?

Why does member assignment fail in initializer list but not in the constructor?

我正在编写遵循以下讨论的成员依赖方案的代码:

Resolve build errors due to circular dependency amongst classes

在最简单的形式中,代码 headers 如下所示:

A.h

class B;
class A{
 public:
   A();
   void send(int i);
   B* b;
};

B.h

#include A.h
#include foo.h

class B : public foo{

 public:
  B(A *a);
  A *a;
  void send(int i); //this invokes a member function of a
};

现在,在我的源代码中,如果我使用如下所示的初始化列表:

A.cpp

A::A() : b(this){};

我收到编译器错误消息“错误:无法在初始化时将‘A* const’转换为‘B*’

但是,如果我不使用初始化列表,而是使用新的指针声明,它编译得很好:

A::A(){
b = new B(this);
}

谁能帮我解释为什么初始化列表导致编译器误解 class B 构造函数参数?或者可能发生了其他事情?

为了以防万一,这里是 B.cpp 文件:

B.cpp

#include "B.h"
#include "A.h"

B::B(A *inst){
    a = inst;
}

void B::send(int i){
    a->send(i);
}

在您的作业中:

b = new B(this);

您正在从 this 构造一个 B 对象,并将指向该对象的指针分配给 b。您需要在成员初始化列表中做同样的事情:

A::A() : b(new B{this}){};

首先,让我们消除噪音并最小化您的示例:

struct A;
struct B { B(A*) {} };

struct A {
    A() : b(this) { }; // error: cannot convert 'A*' to 'B*' in initialization
    B* b;
};

int main() {}

A 的数据成员 bB* 类型而不是 B 类型,我们可以进一步简化示例:

struct A {};
struct B { B(A*) {} };

int main() {
    A a{};
    A* pa = &a;
    B* pb{pa};  // error: cannot convert 'A*' to 'B*' in initialization
}

错误消息现在非常具有解释性(考虑到简单的上下文):我们根本无法

  • 通过指向 A.
  • 的指针初始化指向 B 指针

B 的构造函数在这里不相关,因为它提供了一种方法:

  • 通过指向 A.
  • 的指针初始化 B 类型的 对象
然而,

new 运算符动态创建对象 和 returns 指向它的指针 ,这意味着:

B* pa{new B(pa)};

是:

  • 通过指向 B 的指针初始化指向 B 的指针,该指针 指向 一个 对象 类型 B 由指向 A.
  • 的指针初始化