声明冲突(外部基准与衍生基准)

时间:2019-09-30 13:03:20

标签: c++ inheritance extern

简单的例子:

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 theThingextern PublicInterface theThing冲突。好的,我还有其他选择,例如让大多数其他代码可以使用全局指针(extern PublicInterface *publicThing)(并且在初始化期间将其设置为publicThing = &theThing)。我还可以将它们全部包装在一个名称空间中,而不是一个类中(该设备将永远不会有两个GSM模块),或者我可以玩一些技巧来禁用实现中的源extern PublicInterface theThing可能希望访问更具体的内容-改为使用extern PrivateImplementation theThing),甚至可以使用。

问题是:那为什么会出错?当我在某些来源中有extern PublicInterface theThing,在其他来源中有extern PrivateImplementation theThing而{{1} }(只有一个)(IAR EWARM-以ATSAM4L为目标)。

我可能想到的问题:

  1. 虚拟方法(在派生类中,但不在基类中)或多重继承(在派生类中,第二个基类)。技术上的小问题,但可以解决:链接器需要知道引用哪种类型以注入适当的地址-对于公共访问而言可能有所不同(更高),实际上位于派生内部(在vmt或第一个基类之后) 。编译器可以使用指针(在该PrivateImplementation theThing;中可以轻松地将指针转换为派生指针,也可以将指针转换为基指针),因此它可以(理论上)对全局变量-可求解。

  2. 方法隐藏(其中可能包括对析构函数的显式调用)。没问题,如果我们在声明中说出我们要查看和使用的内容(最后一个声明获胜)。

  3. 允许更改的规则-不能publicThing = &theThing一次声明,int第二次声明,否则至少应该警告。

有什么真正的问题吗? (我的意思是无法解决。)

可能出什么问题了? (例如,当我在某些来源中使用double而在其他来源中使用extern Public...的技巧时,却绝不会两者都使用,永远不会触发冲突,使某些东西正常运行。)

编辑-对一些评论的回复:

因此,您基本上是将我指向One Definition Rule。这至少是我所担心的部分答案(是的,坚持使用指针-extern Private...,不要玩弄把戏)。并没有真正回答 why 部分,但链接中的示例本身显示了它可能在编译器中触发的问题(没有看到publicThing是两个不同来源中的两个不同事物)。同样,幸运我没有提到我自己提到的第一个问题(多重继承)。仍然没有回答为什么,但这对于堆栈溢出来说可能太概念化了,对吧?

1 个答案:

答案 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