【问题标题】:How can I best use polymorphism on incomplete types in C++如何在 C++ 中的不完整类型上最好地使用多态性
【发布时间】:2013-05-09 09:38:23
【问题描述】:

我已经在 stackoverflow 和 google 上寻找了一段时间,但我似乎无法找到有关循环引用、不完整类型和多态性的具体问题的答案。

我希望我能在不发布大量代码的情况下解释这个问题,但是如果我失败了,请告诉我,我会尝试写一个简单的例子。

我有 2 个类,它们都相互使用(比如 COne 和 CTwo 类)。此外,COne 类有一个基类(比如 BaseOne)。

我使用标头保护(如果您这样称呼它们)和不完整的类型来“解决”循环依赖问题。

在顶部的头文件中:

#pragma once

CTwo 的 C++ 文件顶部的某处:

class COne;

现在遇到的问题是,由于类型不完整,编译器似乎不知道COne是从BaseOne派生的。 所以在一个返回类型为 BaseOne* 的函数中,我想返回一个 COne*,这应该是可能的,因为它是一个向下转换,但它说它们不是同一类型。 我现在使用 C 风格的演员修复了这个问题

return (BaseOne*)m_c_one;

我想问的是:有没有比使用 C 风格转换更好的方法来解决这个问题?

【问题讨论】:

  • 将您的成员函数定义放在单独的 .cpp 文件中。但是一个 .cpp 并不意味着一个类。您可以将两个类的成员放入一个 .cpp 文件中,包括包含类声明和编译的标头。这将解决大多数问题。
  • 你的头文件中有return (BaseOne*)m_c_one;吗?
  • 如果你的返回是在 cpp 文件中,整个头文件应该已经被读取,所以编译器应该知道,COne 派生自 BaseOne。
  • 感谢您的建议。实际上,通常我将所有成员函数放在一个 cpp 文件中,但因为它只是一个 1 行的 get 函数,所以我将它直接放在类声明中。现在我知道如何解决它了。

标签: c++ polymorphism circular-dependency incomplete-type


【解决方案1】:

C 风格的转换是不安全的,因为不能保证COne 对象和它的BaseOne 子对象具有相同的内存地址(如果COne 是标准布局类,则可以保证(9p7) ,但这通常排除了多态性)。

编译器需要完成 COne 才能执行转换 (3.2p5),因为 COne 可以使用虚拟继承或多重继承,而且通常因为多态类不需要具有简单的内存布局。

struct COne: BaseZero, BaseOne { ... };
struct COne: virtual BaseOne { ... };

您将不得不将强制转换移动到源文件中COne 的定义可用的点,或者编写自己的强制转换函数BaseOne *to_base(COne *),并在源文件中的某个点实现其中COne 的定义可用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-30
    • 2011-11-18
    • 1970-01-01
    • 2013-09-15
    • 2016-10-06
    • 2018-08-20
    • 2023-03-29
    • 1970-01-01
    相关资源
    最近更新 更多