【问题标题】:Issue with dynamic_cast requiring class definition to be defined prior to the code需要在代码之前定义类定义的 dynamic_cast 问题
【发布时间】:2019-06-26 06:18:31
【问题描述】:

我目前在 dynamic_cast 以及我的代码结构方面遇到了问题。所以我有 Manager 类,它获取一个指针并尝试检查它是否是 Derived 对象,如果是,则在 if 语句中运行一些附加代码。但是为了使 dynamic_cast 起作用,它需要类定义在实际的 dynamic_cast 使用之前。

所以我交换了类 Manager 和类 Derived 定义的位置,以使 Derived 类的定义早于 Manager 类。但是现在,我收到错误消息说“Manager”是一个未定义的类型。我猜为了将 Manager 作为引用传递,Derived 类需要首先定义 Manager 的类定义。

我能想到的最佳解决方案不是将 Manager 类作为引用传递,而是将其作为指针传递(我不太喜欢它,因为我知道 Manager 类将始终是一个有效的指针,所以它使它成为指针毫无意义)。我只是想知道是否有比我现有的更好的替代解决方案。

非常感谢您!

编辑:不幸的是,我需要将所有类定义和实现放在一个文件中,因此将它们拆分为 .h 和 .cpp 文件不太理想。有人问,是的,这是家庭作业,但我的教授希望它在一个文件中。

class BaseClass
{
    virtual VirtualClassName() = 0;
};

class Manager
{
    void FunctionNameOne(const BaseClass* const ClassPointer)
    {
        if(Derived* DerviedPtr = dynamic_cast<Derived*>(ClassPointer))
        {
            //Do stuff with DerviedPtr
        }
    }   
};

class Derived : public BaseClass
{
    Void FunctionNameTwo(const Manager& Manager)
    {
        //Do stuff with Manager
    }
};

【问题讨论】:

  • 首先你需要在你的类定义后面加上分号。
  • 通常的做法是让变量以小写字符开头(或者在成员变量的情况下以下划线+小写字母开头)。很难判断你是指类型 Manager 还是实例(嗯,常量引用)const Manager&amp; Manager 否则。
  • 您熟悉“前向声明”的概念吗?它可能正是您所需要的。
  • 您的问题确实源于使用dynamic_cast 的愿望。修复那个;重组你的代码,这样你就不需要它了。为什么Manager::FunctionNameOne 需要知道Derived,即使它需要BaseClass 作为类型?

标签: c++ dynamic-cast


【解决方案1】:

通常,您将声明放入项目的 .h 文件中,将方法的实现放入 .cpp 文件中。

如果您遵循这种方式,则所有类定义都是已知的,您可以在这种情况下毫无问题地使用动态转换。

【讨论】:

  • 我已经编辑了我的问题,如果将它们拆分为 .h 和 .cpp 文件不理想,有什么好方法?
  • @JamesL 您仍然可以将方法定义移动到同一文件的底部
  • 哦!我明白你的意思了!非常感谢,我认为这比让一个函数接受指针要好。
  • 请注意,您可能仍需要前向声明才能在顶部写出函数声明。
【解决方案2】:

我必须清理代码,您至少应该有格式良好的代码可以使用,否则您的错误消息将毫无意义。

class BaseClass
{
    virtual void VirtualClassName() = 0;
};

class Manager
{
    void FunctionNameOne(const BaseClass* const ClassPointer);
};

class Derived : public BaseClass
{
    void FunctionNameTwo(const Manager& Manager)
    {
        //Do stuff with Manager
    }
};

void Manager::FunctionNameOne(const BaseClass*  ClassPointer)
{
    if (const Derived* DerviedPtr = dynamic_cast<const Derived*>(ClassPointer))
    {
        //Do stuff with DerviedPtr
    }
}

请注意,我在声明 Derived 之后定义了 FunctionNameOne 并使用了动态转换。

【讨论】:

  • 抱歉,我会在以后的帖子中记住这一点。我想让他们中的一个拿一个指针将是我最好的投篮。
猜你喜欢
  • 1970-01-01
  • 2012-07-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-29
  • 2019-08-01
  • 2014-06-16
相关资源
最近更新 更多