【问题标题】:inheritance c++继承 C++
【发布时间】:2023-04-06 04:28:01
【问题描述】:

我有两节课。

class A:

class B: public A
{
     //new function
     void setHint(...);
}

并且有结构数据。

typedef std::shared_ptr<A> window_ptr;
std::stack<window_ptr> m_windowsStack;
m_windowsStack.push(std::make_shared<A>("Hint"));
m_windowsStack.push(std::make_shared<B>("Game"));

并在堆栈中找到函数:

std::shared_ptr<A> WindowManager::findWindow(std::string title)
{
    ... return result;
}

并使用函数在堆栈中查找元素:

auto w = findWindow("Game"); //return element type B 
w->setHint(window);

但事实证明,findWindow 函数返回 type A。我得到错误“'class A'没有名为'setHint'的成员 w->setHint(window);"

我需要将 A 类中的 setHint 函数声明为虚函数吗?如何让变量自动理解为 B 类型?

【问题讨论】:

  • 只转换结果,即auto w = findWindow("Game"); -> auto w = static_cast&lt;B*&gt;(findWindow("Game"));
  • class A:是错误,请写真实代码。另外我不确定您是否打算将setHint 用作可变参数
  • @M.M class A:{}这是抽象类,我的类很大,对于这个问题\函数有很多不必要的变量。 :)

标签: c++ c++11 inheritance virtual


【解决方案1】:

在不了解您的整个项目的情况下,我会说正确的解决方案可能是在基类中添加一个虚函数。

class A {
 public:
  virtual void setHint(/*...*/) { /* some default implementation */}
  // or pure virtual
  virtual void setHint(/*...*/) = 0;

  virtual ~A() = default; // base class should have a virtual destructor
};

class B: public A {
 public:
  void setHint(/*...*/) override;
};

或者,如果您知道确定指向来自findWindow 的返回值的类型是B,您可以简单地static_pointer_cast 向下

auto w = std::static_pointer_cast<B>(findWindow("Game"));
w->setHint(window);

如果您不确定,并且A 是多态类型(具有任何virtual 函数),您可以dynamic_pointer_cast 并检查是否为空

if (auto w = std::dynamic_pointer_cast<B>(findWindow("Game"))) {
  w->setHint(window);
}

【讨论】:

  • 另一个选项是dynamic_cast&lt;B&amp;&gt;(*w).setHint(window); - 如果它不是预期的类型,这将引发异常而不是未定义的行为
  • @M.M 对,但如果 OP 试图不添加虚拟功能,则不然
  • 他在对A是抽象类的问题的评论中说(暗示它已经包含虚函数)
  • 您可能希望使用cast operators for shared_ptr 而不是转换存储的原始指针。
  • @Holt 确实,这确实消除了额外的变量
【解决方案2】:

您的选择是:

  1. 在 A 类中声明 setHint 虚拟

  2. 使用dynamic_pointer_cast

这样

auto w = std::dynamic_pointer_cast<B>(findWindow("Game"));
assert(w);  // Will be nullptr if cast fails.
w->setHint(window);

【讨论】:

    猜你喜欢
    • 2015-04-19
    • 2012-10-30
    • 2010-11-05
    • 2016-03-02
    • 1970-01-01
    • 2017-03-31
    • 2012-02-13
    • 2015-12-09
    • 1970-01-01
    相关资源
    最近更新 更多