简单示例:
class PublicInterface {}; // e.g. GSM driver with 'send_sms'
extern PublicInterface theThing; // for most of the code (in common header)
class PrivateImplementation : public PublicInterface {}; // implementation not all need to know about
PrivateImplementation theThing; // the one and only GSM driver with all it needs to work
不会编译,抱怨PrivateImplementation theThing
与extern PublicInterface theThing
冲突。好的,我还有其他选择,例如让大多数其他代码可以使用全局指针(extern PublicInterface *publicThing
)(并且在初始化期间将其设置为publicThing = &theThing
)。我也可以将它们全部包装在名称空间中,而不是类中(设备永远不会有两个GSM模块),或者我可以玩技巧来通过实现(以及任何其他可能希望禁用的源代码)禁用extern PublicInterface theThing
访问更具体的内容-改为使用extern PrivateImplementation theThing
,它甚至可以工作。
问题是:为什么会出现错误?当我在某些来源中具有extern PublicInterface theThing
,在其他来源中具有extern PrivateImplementation theThing
而在一个来源中只有PrivateImplementation theThing;
时,它就可以正常工作(IAR EWARM-以ATSAM4L为目标)。
我可能想到的问题:
虚拟方法(在派生类中,但不在基类中)或多重继承(基类在派生类中为第二个)。技术上的小问题,但可以解决:链接器需要知道引用哪种类型以注入适当的地址-对于公共访问而言可能有所不同(更高),实际上位于派生内部(在vmt或第一个基类之后) 。编译器可以使用指针(在publicThing = &theThing
中可以轻松地将指针转换为派生指针,然后将指针转换为指向base的指针),因此它(理论上)可以对全局变量-可求解。- 方法隐藏(可能包括对析构函数的显式调用)。没问题,如果我们在声明中说出我们要查看和使用的内容(最后一个声明获胜)。
- 允许更改的规则-一次不能声明为
int
,第二次不能声明为double
,或者至少应该警告。 有什么真正的问题吗? (我的意思是无法解决的。)
可能出什么问题? (例如,当我玩弄在某些来源中使用extern Public...
而在其他来源中使用extern Private...
的技巧时,却绝不会两者都使用,永远不会触发冲突,使某些内容正常运行。)
编辑-对一些评论的回复:
所以,您基本上是将我指向One Definition Rule。这至少是我所关心的问题的部分答案(是的,坚持使用指针-publicThing
,不要耍花招)。并没有真正回答why
部分,但是链接本身中的示例显示了它可能在编译器中引发哪些问题(没有看到CDummy
是两个不同来源中的两个不同事物)。另外[luck我没有提到我自己提到的第一个问题(多重继承)。仍然没有回答
why,但是对于Stack Overflow来说可能太概念了,对吧?简单的例子:class PublicInterface {}; //例如带有“ send_sms”外部PublicInterface theThing的GSM驱动程序; //对于大多数代码(在公共标头中)类PrivateImplementation:public ... “为什么”问题有点难以理解。 theThing
是代码中对象的名称(不是指针或对其的引用)。 C ++是静态类型的语言,因此一个对象实际上只能是一种类型。期。您可以在C ++中使用多态指针或引用。因此,您需要执行以下操作:
class PublicInterface {}; // e.g. GSM driver with 'send_sms'
extern PublicInterface& theThing; // declaration of reference
class PrivateImplementation : public PublicInterface {}; // implementation not all need to know about
PrivateImplementation thing; // the one and only GSM driver with all it needs to work
PublicInterface& theThing = thing; // definition of the reference to thing