繁体   English   中英

在C ++中从指针向量访问子类变量到超类

[英]Access subclass variables from vector of pointers to superclass in C++

如果我有一个指向超类的指针的向量,并将一个子类的成员添加到该向量,则可以很好地调用子类函数,但是由于我的代码现在正确,所以我无法访问该子类唯一的变量。 如何从vec的指针访问B

#include <iostream>
#include <vector>

class Super {
  public:
    int A;
    Super(int a) : A(a) {}
    virtual void foo() = 0;
};

class Sub : public Super {
  public:
    int B;
    Sub(int a, int b) : Super(a), B(b) {}
    void foo() {
      std::cout << "calling foo from Sub\n";
    }   
};

int main() {
  std::vector<Super*> vec;
  vec.push_back(new Sub(2, 3));
  vec[0]->foo();                                // No problem
  std::cout << "A: " << vec[0]->A << std::endl; // No problem
  std::cout << "B: " << vec[0]->B << std::endl; // Compile Error
}

这取决于设计。 “强制”方式是将值转换为子类型,例如:

std::cout << static_cast<Sub*>(vec[0])->B;

现在,这是不好的原因是因为您将一个类型显式转换为另一个类型,这违背了抽象和继承本身的目的。

这就是为什么在普通用法中会发生的情况是,您在超类中定义了一组类型的特征,然后在子类中根据需要扩展或实现了它。 现在这不可能,就像在测试用例中一样,但是原则上这就是为什么要照管的原因。

您可以使用dynamic_cast<Sub*> (或者如果可以保证每个指针都指向Sub ,则可以使用static_cast<Sub*>来天真地解决此问题,但是……不要! 这是用于虚拟调度的教科书箱。

我要添加一个virtual void print(std::ostream&) ,它是整个继承层次结构的接口一部分 ,以及一个可以在该层次结构内的任何类型的对象上调用的operator<< 让C ++运行时多态性和函数重写的魔力为您完成所有这些工作,因此main不需要知道AB之间的差异或每个成员具有哪些成员变量,也不需要弄清楚每个指针属于哪种对象实际指向。

您还应该存储一个智能指针,以避免内存泄漏。

#include <iostream>
#include <vector>
#include <memory>

struct Super {
    int A;
    Super(int a) : A(a) {}

    virtual void foo() = 0;
    virtual void print(std::ostream& os) const
    {
        os << "A: " << A << '\n';
    };
};

struct Sub : Super {
    int B;

    Sub(int a, int b) : Super(a), B(b) {}

    void foo() { std::cout << "calling foo from Sub\n"; }
    virtual void print(std::ostream& os) const
    {
        Super::print(os);
        os << "B: " << B << '\n';
    }
};

std::ostream& operator<<(std::ostream& os, const Super& obj)
{
    obj.print(os);
    return os;
}

int main()
{
   std::vector<std::unique_ptr<Super>> vec;
   vec.emplace_back(std::make_unique<Sub>(2, 3));
   vec[0]->foo();
   std::cout << *(vec[0]);
}

现场演示

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM