2013-05-09 73 views
2

我一直在寻找stackoverflow和谷歌一段时间,但我似乎无法找到一个关于循环引用,不完整类型和多态性的具体问题的答案。如何在C++中最好地使用不完整类型的多态性

我希望我可以解释这个问题,而不会发布很多代码,但如果我失败了,请让我知道,我会尝试写下一个简单的例子。

我有两个类,它们都使用对方(说COne和CTwo类)。另外,COne类有一个基类(比如BaseOne)。

我使用标题警卫(如果你称它们为)和不完整的类型来“解决”循环依赖问题。

在顶部的头文件:

#pragma once 

,并在为CTWO的C++文件顶部的地方:

class COne; 

现在我遇到的问题是,由于不完整的类型的,编译器似乎并不知道COne是从BaseOne派生的。 因此,在一个返回类型BaseOne *的函数中,我想返回一个COne *,这应该是可能的,因为它是一个downcast,但它表示它们不是相同的类型。 我已经解决了这个问题现在用的是C样式转换

return (BaseOne*)m_c_one; 

我想问什么:有没有更好的办法来解决这个然后使用C样式转换?

+1

将您的成员函数定义放入单独的.cpp文件中。但是,一个.cpp并不意味着一个班级。您可以将来自两个类的成员放入一个.cpp文件中,包含包含类声明和编译的头文件。这将解决大部分问题。 – stardust 2013-05-09 09:43:56

+0

你在头文件中有'return(BaseOne *)m_c_one;'吗? – 2013-05-09 09:46:12

+0

如果你的返回是在cpp文件中,那么整个头文件应该已经被读取了,所以编译器应该知道,COne是从BaseOne派生的。 – Spook 2013-05-09 09:49:33

回答

1

的C样式转换是不安全的,因为它不能保证本COne对象及其BaseOne子对象具有相同的存储器地址(如果COne是一个标准的布局类(9p7它被保证的),但是这一般阻碍多态)。

编译器需要COne,因为有一个简单的内存布局多态类不需要完整来执行转换(3.2p5),因为COne可以使用虚拟或多重继承,和一般。

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

你将不得不要么被实现在一个点移动要转换成点源文件,其中的COne的定义是可用的,或者自己写转换函数BaseOne *to_base(COne *)在源文件中其中COne的定义可用。