简单的例子:
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
而{{1} }(只有一个)(IAR EWARM-以ATSAM4L为目标)。
我可能想到的问题:
虚拟方法(在派生类中,但不在基类中)或多重继承(在派生类中,第二个基类)。技术上的小问题,但可以解决:链接器需要知道引用哪种类型以注入适当的地址-对于公共访问而言可能有所不同(更高),实际上位于派生内部(在vmt或第一个基类之后) 。编译器可以使用指针(在该PrivateImplementation theThing;
中可以轻松地将指针转换为派生指针,也可以将指针转换为基指针),因此它可以(理论上)对全局变量-可求解。
方法隐藏(其中可能包括对析构函数的显式调用)。没问题,如果我们在声明中说出我们要查看和使用的内容(最后一个声明获胜)。
允许更改的规则-不能publicThing = &theThing
一次声明,int
第二次声明,否则至少应该警告。
有什么真正的问题吗? (我的意思是无法解决。)
可能出什么问题了? (例如,当我在某些来源中使用double
而在其他来源中使用extern Public...
的技巧时,却绝不会两者都使用,永远不会触发冲突,使某些东西正常运行。)
编辑-对一些评论的回复:
因此,您基本上是将我指向One Definition Rule。这至少是我所担心的部分答案(是的,坚持使用指针-extern Private...
,不要玩弄把戏)。并没有真正回答 why 部分,但链接中的示例本身显示了它可能在编译器中触发的问题(没有看到publicThing
是两个不同来源中的两个不同事物)。同样,幸运我没有提到我自己提到的第一个问题(多重继承)。仍然没有回答为什么,但这对于堆栈溢出来说可能太概念化了,对吧?
答案 0 :(得分:1)
“为什么”问题有点难以理解。 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