【问题标题】:Polymorphism with class member objects类成员对象的多态性
【发布时间】:2025-12-13 00:10:01
【问题描述】:

我想知道当您正在操作的对象存储在类中(而不是作为指针或引用类型)时,C++ 中的多态性如何工作。

我读过多态性只对指针和引用起作用,但是我重载了

在我的实现中测试这个示例时,我发现它没有按预期工作,并且将返回基类字符串(“A”)而不是“B”。

这是因为对象存储在类本身内部吗?并且

class Test {

    public:
       void Run() {
           object_ = B();
           std::cout << object_ << std::endl;
       }


    private:
       A object_;
};

Class A {
    // Assume this is already implemented. All it does it add obj.getType()
    // to stream
    friend ostream& operator<<(ostream& stream, A obj);

    public:
      virtual std::string getType() {
             return std::string("A");
      }
};

Class B : public A {
    public:
      std::string getType() {
            return std::string("B");
      }
};

int main(int argc, char* argv[]) {
    Test test = Test();
    test.Run();
}

【问题讨论】:

标签: c++ class polymorphism virtual


【解决方案1】:

你的班级中有一个A 对象,所以当你这样做时:

object_ = B();

RHS 上的 B 对象被切片。见object slicing。这与作为类成员的对象无关,可以用一个更简单的例子来说明:

int main()
{
  B b;
  A a;
  a = b;
  std::cout << a << "\n";
}

【讨论】:

  • 所以如果我将 A 对象类型更改为 Test 内部的 A*,它可以在不切片的情况下工作吗?
  • @Antix 确保删除所有新指针,或使用智能指针而不是原始指针。
  • 如果我在正确的轨道上,那是为了避免内存泄漏?
  • @Antix 是的。好吧,严格来说,以便调用必要的析构函数。这些不仅可以释放资源,还可以关闭文件句柄、套接字、减少引用计数……
  • 我要补充一点,切片已完成,因为如果从 A 继承的对象 B 的大小大于对象 A,则“测试”类中没有额外数据的空间。这就是为什么你不能直接对成员对象进行多态化。