#c #private-inheritance
#c #private-наследование
Вопрос:
например, этот код
class Try
{
public:
Try() = default;
int i = 0;
};
class B1 : private Try
{
public:
B1() = default;
using Try::Try();
using Try::i;
};
class C1 : public B1
{
public:
Try a; //tell me:'Try' is a private member of 'Try'
void print()
{std::cout << i << std::endl;}
//Access to this I is allowed;
};
Попытка a является локальным объектом, а не частью C1, почему ошибка?
Если это прямой базовый класс частного наследования, разве невозможно определить объект косвенного базового класса в его производном классе? Это потому, что конструктор нельзя использовать или по другим причинам?
Комментарии:
1. Не могли бы вы опубликовать полное сообщение об ошибке дословно на свой вопрос?
Ответ №1:
Попытка a является локальным объектом, а не частью C1, почему ошибка?
При записи Try a;
в контексте class C1
поиск имени обычно всегда будет сканироваться из локальной области в глобальную. Таким образом, первое совпадение будет B1::Try
, которое из-за частного наследования недоступно для C1
.
Исправить это легко, просто намекните компилятору имя, которое вы «действительно» имеете в виду, т. Е. написав, например ::Try a;
.
Комментарии:
1. Я понимаю, что класс c1 принадлежит локальной области видимости. Я все еще не понимаю, почему локальное действие не может определить объект? Это из-за частного наследования?
2. @Nater Да, вы получаете доступ
Try
«через призму»B1
, посколькуB1
следующий контекст для компилятора для поиска имениTry
, который недоступенC1
. Тем не менее,B1::Try
действительно существует (из-за наследования), но он недоступен дляC1
(поскольку наследование является частным), поэтому извнеB1
недопустимо утверждать, чтоB1
это производное отTry
. Компилятору все равно,B1::Try
доступен он или нет, он нашел имя, которое работает, и останавливает поиск другогоTry
. Вот почему вы должны получить доступTry
на глобальном уровне,::Try
чтобы дать подсказку.3. У меня есть некоторое понимание, но у меня все еще есть вопрос: пока это частное наследование, невозможно ли определить объект косвенного базового класса в его производном классе? Хотя конструктор прямого базового класса объявлен как общедоступный, я внес некоторые изменения в код
4. @Nater Нет, это не невозможно. Как я уже писал, если вы обращаетесь к нему с помощью
::Try a;
, вы можете определить объект косвенного типа базового класса, когда действует частное наследование. Сделав конструктор доступным, вы все равно не сможете его использоватьB1::Try
, поскольку с точки зрения контроля доступа любое предположение о наследовании запрещено (из-за конфиденциальности).5. @Nater — Нет — как говорится в этом ответе — частное наследование не препятствует использованию экземпляра базового класса в качестве члена производного класса. Необходимо убедиться, в контексте
C1
, что тип члена назван правильно (т. Е. Что член указан как::Try a
, а неTry a
как ).::Try
является полным именемTry
, в вашем примере.