为什么在使用构造函数后指针向量没有保存为 class 成员?

Why is vector of pointers not saved as a class member after using the constructor?

我写了一个奇怪的例子,我实例化了一个对象,给它一堆相似的对象,然后我尝试使用相似的对象在主对象上调用一个函数。

我想将指针向量保存为 class 成员,如

#include <iostream>
#include <vector>

class A {
  public: 
    virtual ~A() = default;
};

class B: public A {
  public:
    std::vector<B*> bees;

    B() {};

    B(std::vector<B*> bees) {
      bees = bees;
    }

    int h() {
      return 2;
    }

    void fly() {
      std::cout << bees.size() << std::endl;
      std::cout << bees[0]->h() << std::endl;
    }
};

int main() {
  std::cout << "hello world" << std::endl;

  B b1, b2, b3;

  std::vector<B*> bs {&b1, &b2, &b3};
  B(bs).fly();

  return 0;
}

但出于某种原因,我得到了

hello world
0
Segmentation fault (core dumped)

我不确定这是否与阴影有关,但我无法弄清楚。

我期待

hello world
3
2

在构造函数主体中,bees = bees; 正在分配构造函数参数 bees(本身),而不是数据成员 bees。当 fly() 被调用时,数据成员 bees 仍然是空的,并且 bees[0] 正在尝试访问不存在的第一个元素;这导致 UB。

你可以改成

B(std::vector<B*> bees) {
  this->bees = bees;
}

或者通过成员初始化列表初始化数据成员

B(std::vector<B*> bees) : bees(bees) {}
bees = bees;

这没有任何作用。它将 bees 分配给自己。它很可能会优化到什么都没有。

this->bees = bees;

这会将局部变量显式分配给实例字段,这正是您要执行的操作。

B(std::vector<B*> bees) : bees(bees) {}

但是,这是最佳实践,因为它使用构造函数初始化语法在 class 本身的同时初始化字段。