【问题标题】:Get properties of derived class from base class argument从基类参数获取派生类的属性
【发布时间】:2022-01-08 08:29:37
【问题描述】:

我不知道如何问这个问题,但基本上我将基类作为参数传递,如果参数是基类的派生类,我希望只能访问派生类中的属性

class A{
public:
  bool isB = false; 
  int x = 69;
}
class B : public A{
public:
  bool isB = true;
  int y = 420;
}
void Print(A c){
  if (c.isB)
    cout << c.y << endl; //this will error as the class A has no y even though i will pass class B as an argument
  else
    cout << c.x << endl;
}

A a;
B b;

Print(a);
Print(b);

【问题讨论】:

  • 您的Print() 函数是slicing 的输入参数,因此无法将B 对象放入其中。您需要通过指针 (A*) 或引用 (A&amp;) 来传递参数。然后Print() 可以使用dynamic_cast 访问B 的成员。但这不是针对这种情况的好设计。您应该向 A 添加一个虚拟的 print() 方法,以便 B 覆盖,正如 this answer 所建议的那样。

标签: c++ class


【解决方案1】:

我的建议是您使用 多态性,方法是创建一个您的全局 Print 函数调用的虚拟“打印”函数:

class A
{
    int x = 69;

public:
    virtual ~A() = default;  // Needed for polymorphic classes

    virtual void print(std::ostream& out) const
    {
        out << x;
    }
};

class B : public A
{
    int y = 420;

public:
    void print(std::ostream& out) const override
    {
        out << y;
    }
};

void Print(A const& o)
{
    o.print(std::cout);
    std::cout << std::endl;
}

int main()
{
    A a;
    B b;

    Print(a);
    Print(b);
}

【讨论】:

    【解决方案2】:

    您需要在返回“isB”的基类和派生类中定义一个虚函数“bool amIaB()”。

    【讨论】:

    • 虽然这可行,但它绝对是一种设计味道。基类不需要知道关于它的子类的这种细节。
    • 这无论如何都行不通,因为y 中仍然不存在A 以供Print() 访问。 Print() 必须使用 dymamic_castA 转换为 B 才能访问 y。否则,更好的选择是将virtual 方法添加到A 以返回/打印x,并让B 覆盖该方法以返回/打印y,然后Print() 可以调用该方法在给定的A 上,无论其实际类类型如何。
    猜你喜欢
    • 2017-11-05
    • 2015-03-30
    • 1970-01-01
    • 2022-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多