Конфликтующее объявление (внешняя база против производной) - PullRequest
0 голосов
/ 30 сентября 2019

Простой пример:

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).

Возможные проблемы, о которых я могу подумать:

  1. Виртуальные методы (в производном, но не в базовом классе) или множественное наследование (базовое является вторым в производном). Небольшая техническая проблема, но решаемая: компоновщик должен знать, под каким типом он был указан, чтобы ввести правильный адрес - может быть другим (немного выше) для публичного доступа, который фактически живет внутри производного (после vmt или первого базового класса),Компилятор может работать с указателем (легко преобразовать указатель в производное в указатель на базу в этом publicThing = &theThing), поэтому он может (теоретически) сделать это для глобальной переменной - разрешимый.

  2. Скрытие метода (которое может включать явный вызов деструктора). Не проблема, потому что мы говорим в объявлении, что мы хотим видеть и использовать (выигрывает последнее объявление).

  3. Правила, изменения которых разрешены - нельзя объявить это int один раз иdouble во второй раз, или он должен хотя бы предупредить.

Есть ли реальные проблемы? (Я имею в виду что-то неразрешимое.)

Что может пойти не так? (например, когда я разыгрываю трюк, чтобы использовать extern Public... в некоторых и extern Private... в других источниках, но не в обоих одновременно, никогда не вызывая конфликт, получая что-то, что работает должным образом.)

EDIT - Responseна некоторые комментарии:

Итак, вы в основном указываете мне на Одно определение правила . Это хотя бы частичный ответ на мои вопросы (да, придерживайтесь указателя - publicThing, не играйте в шутки). На самом деле не отвечает на вопрос почему , но пример в самой ссылке показывает, какие проблемы он может вызвать в компиляторе (не видеть, что CDummy - это две разные вещи в двух разных источниках). Также удача , что я не вызвал первую проблему (множественное наследование), которую я сам упомянул. Все еще не отвечая на почему , но это может быть слишком концептуально для переполнения стека, верно?

1 Ответ

1 голос
/ 30 сентября 2019

Вопрос «почему» немного сложен для понимания. 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
...