#c #inheritance #struct #declaration #friend
Вопрос:
Мне нужно скомпилировать что-то вроде этого:
struct Base { virtual void func1()=0; // ... friend void Derived::func2(Base *base); private: int some_private; } struct Derived : Base { virtual func3()=0; // ... void func2(Base *child) { std::cout lt;lt; child-gt;some_private; } };
Но я продолжаю получать ошибки компиляции. Я попытался сначала поменять структуры местами или объявить их, но я не могу сначала объявить производные (из-за наследования), и я не могу сначала объявить базу (потому что мне нужно объявить функцию друга в производных). Что делать?
Комментарии:
1. Подумайте о том , чтобы объединить все
struct Derived
вместе или заменитьprivate
наprotected
.2.@Фрэнк — создание
some_private
protected
не позволилоchild-gt;some_private
бы войтиfunc2
. Объекты производных типов имеют доступ к своим собственным унаследованным защищенным элементам, но не к защищенным элементам других объектов.3. У тебя проблема с курицей и яйцом. Вы не можете добавлять функции-члены в
friend
объявление; компилятор должен был видеть определениеDerived
,Derived::func2
чтобы быть действительным. Это отличается от функций, не являющихся членами, где afriend declaration
также служит объявлением этой функции. Так что лучше всего объявитьDerived
себя другом.4. @PeteBecker Спасибо за информацию, я ожидал, что это будет соответствовать
private
доступу к членам других инстансов.5. @Фрэнк — да, это естественное ожидание.
protected
это другое, и я не помню, почему это так, но для этого есть веская причина.
Ответ №1:
У вас есть несколько основных решений. Наиболее очевидным является переход от частного к защищенному. В C защищенный означает, что подклассы имеют доступ.
Вместо этого вы можете добавить более общедоступные (возможно, защищенные) методы доступа.
Вы можете перенаправить ссылку на весь производный класс и подружиться со всем классом.
Лично я никогда не чувствовал необходимости использовать методы или классы друзей, и я не знаю, при каких обстоятельствах мне пришлось бы оказаться, прежде чем я не стал бы зависеть от других способов достижения того, чего я пытаюсь достичь.
Для этого конкретного решения я бы изменил доступ на защищенный.
Комментарии:
1. Спасибо, я сделаю весь класс другом, потому что мне не разрешено делать функцию защищенной.
2.
protected
не сработает. Объекты производных типов имеют доступ к своим собственным унаследованным защищенным элементам, но не к защищенным элементам других объектов.child-gt;some_private
пытается использовать защищенный элемент другого объекта, поэтому это запрещено.3. @PeteBecker
child
относится к типуBase
-суперкласс. То есть вы хотите сказать, что подкласс не может получить доступ к защищенным членам суперкласса?4. @JosephLarson — нет, я не это сказал. Объект производного типа не может получить доступ к защищенным элементам другого объекта.
5. Не путайте базовый класс с базовым объектом .