简体   繁体   English

如何在C ++中最好地对不完整类型使用多态

[英]How can I best use polymorphism on incomplete types in C++

I've been looking on stackoverflow and google for a while now, but I can't seem to find an answer to my specific question about circular references, incomplete types and polymorphism. 我一直在寻找stackoverflow和google已有一段时间了,但是我似乎找不到关于循环引用,不完整类型和多态性的具体问题的答案。

I hope I can explain this question without posting a lot of code, but if I fail, please let me know and I will try to write down a simple example. 希望我能在不发布大量代码的情况下解释这个问题,但是如果失败,请告诉我,我将尝试写下一个简单的示例。

I have 2 classes, which both use each other (say class COne and CTwo). 我有2个类,它们都互相使用(比如类COne和CTwo)。 Also, class COne has a base class (say BaseOne). 而且,COne类具有基类(例如BaseOne)。

I use header guards (if you call them that) and incomplete types to 'solve' the circular dependency problem. 我使用标头保护符(如果您称呼它们)和不完整的类型来“解决”循环依赖问题。

in the header files on top: 在顶部的头文件中:

#pragma once

and somewhere at the top in the C++ file for CTwo: 在CTwo的C ++文件顶部的某个位置:

class COne;

Now I encounter the problem that, because of the incomplete type, the compiler does not seem to know that COne is derived from BaseOne. 现在,我遇到一个问题,由于类型不完整,编译器似乎不知道COne是从BaseOne派生的。 So in a function which has a return type BaseOne*, I want to return a COne*, which should be possible cause it's a downcast, but it says they are not of the same type. 因此,在一个具有返回类型BaseOne *的函数中,我想返回一个COne *,这应该是可能的,因为它是一个低调的选择,但是它说它们不是同一类型。 I have fixed this now using a C-style cast 我现在使用C风格的演员表修复了此问题

return (BaseOne*)m_c_one;

What I wanted to ask: is there a better way to solve this then using a C-style cast? 我想问的是:是否有比使用C样式转换更好的方法来解决此问题?

The C-style cast is unsafe, because it is not guaranteed that the COne object and its BaseOne subobject have the same memory address (it is guaranteed if COne is a standard-layout class (9p7), but that generally precludes polymorphism). C样式COne是不安全的,因为不能保证COne对象及其BaseOne子对象具有相同的内存地址(可以保证COne是标准布局类(9p7),但通常会阻止多态)。

The compiler needs COne to be complete to perform the cast (3.2p5) because COne could use virtual or multiple inheritance, and in general because polymorphic classes are not required to have a simple memory layout. 编译器需要COne完整才能执行转换(3.2p5),因为COne可以使用虚拟或多重继承,并且通常因为不需要多态类具有简单的内存布局。

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

You're going to have to either move the cast to a point in a source file where the definition of COne is available, or write your own casting function BaseOne *to_base(COne *) with an implementation at a point in a source file where the definition of COne is available. 您将不得不将强制转换移动到COne的源文件中的某个点,或者编写自己的强制转换函数BaseOne *to_base(COne *) ,并在源文件中的某个点处实现COne的定义可用。

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

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