Форум программистов, компьютерный форум CyberForum.ru

Невозможно обратиться к protected член, объявленному в классе "Counter" - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 13, средняя оценка - 4.92
stzer
38 / 59 / 17
Регистрация: 26.10.2013
Сообщений: 172
Завершенные тесты: 2
23.07.2014, 16:07     Невозможно обратиться к protected член, объявленному в классе "Counter" #1
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
typedef unsigned int uint;                                                                            
class Counter
{
protected:
    uint count;
    Counter() : count(0)
    { }
    Counter(int c) : count(c)
    { }
public:
    uint get_count () const
    { return count; }
    Counter operator++()
    { return Counter(++count); }
};
 
class CountDn : public Counter
{
public:
    Counter operator--()
    { return Counter(--count); } //error C2248: Counter::Counter: невозможно обратиться к protected член, объявленному в классе "Counter"
};
 
void main()
{
    CountDn c1;
    cout<<"c1= "<<c1.get_count();
    ++c1; ++c1; ++c1;
    cout<<"\nc1= "<<c1.get_count();
    --c1; --c1;
    cout<<"\nc1= "<<c1.get_count()<<endl;
    system("pause");
}
Скажите почему, ведь у меня перед конструкторами стоит ключевое слово protected.
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
23.07.2014, 16:07     Невозможно обратиться к protected член, объявленному в классе "Counter"
Посмотрите здесь:

У меня класс B в классе A, а в классе B рекурсивная функция переопределения оператора "()", как её вызвать, не создавая явно объект класса B? C++
C++ базовый и производный класс, в базовом объявлена переменная "protected", она недоступна по имени в производном классе! template <class T> воду мутит!
невозможно преобразовать параметр 1 из "const char [8]" в "LPCWSTR" C++
C++ Невозможно обратиться к private член, объявленному в классе "Complex"
error C2664: CWnd::MessageBoxW: невозможно преобразовать параметр 2 из "long" в "LPCTSTR" C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Psilon
Master of Orion
 Аватар для Psilon
5742 / 4690 / 619
Регистрация: 10.07.2011
Сообщений: 14,162
Записей в блоге: 5
Завершенные тесты: 4
24.07.2014, 02:13     Невозможно обратиться к protected член, объявленному в классе "Counter" #21
DrOffset, бредовое поведение. В том же шарпе наследник может спокойно обращаться к полям базового класса, например:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
    class A
    {
        protected int a;
    }
 
    class B: A
    {
        public B()
        {
            B b = this;
            b.a = 10;
        } 
    }
или
C#
1
2
3
4
5
6
7
    class B: A
    {
        public int Sum(B one, B two)
        {
            return one.a + two.a;
        }
    }
интересно, как обосновывается такое решение? То, что это спецификация - понятно, вопрос в логике...
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
24.07.2014, 02:37     Невозможно обратиться к protected член, объявленному в классе "Counter" #22
А если так? Ошибки не будет?
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
class A
    {
        protected int a;
    }
 
    class B: A
    {
        public B()
        {
            А b;
            b.a = 10;
        } 
    }
HighPredator
 Аватар для HighPredator
5351 / 1734 / 320
Регистрация: 10.12.2010
Сообщений: 5,120
Записей в блоге: 3
24.07.2014, 08:13     Невозможно обратиться к protected член, объявленному в классе "Counter" #23
А я не понимаю следующий момент:
Цитата Сообщение от DrOffset Посмотреть сообщение
declaring a constructor
protected ensures that only derived classes and friends can create objects using it
почему собственно не получается делать то, что как раз тут и написано, а именно
create objects using it
? Или я совсем в танке?

Добавлено через 16 минут
Короче, в моем понимании на текущий момент, оно не компилируется потому что сие идет вразрез с пунктом 11.2 стандарта (с номером мог и промахнуться чуть-чуть -- Accessibility of base classes and base class members), который говорит нам следующее:
A member m is accessible at the point R when named in class N if
— m as a member of N is public, or
— m as a member of N is private, and R occurs in a member or friend of class N, or
m as a member of N is protected, and R occurs in a member or friend of class N, or in a member or
friend of a class P derived from N, where m as a member of P is public, private, or protected
, or
— there exists a base class B of N that is accessible at R, and m is accessible at R when named in class B.
. Нас интересует выделенное жирным. А конструкторы не наследуются, значит данный пункт не работает. Хотя люди пишут, что вроде как наследование контрукторов добавили в 11, но мне удалось найти только сведения об их делегировании -- не больше. Такие дела.
Psilon
Master of Orion
 Аватар для Psilon
5742 / 4690 / 619
Регистрация: 10.07.2011
Сообщений: 14,162
Записей в блоге: 5
Завершенные тесты: 4
24.07.2014, 09:48     Невозможно обратиться к protected член, объявленному в классе "Counter" #24
alsav22, хм, а так - нельзя. Любопытно

То есть можно получить доступ к protected-членам через ссылку на объект производного класса внутри этого класса, но если передается ссылка на базовый класс, то доступ к его protected-членам запрещен. Прикольненько
error CS1540: Cannot access protected member `TestApp.A.a' via a qualifier of type `TestApp.A'. The qualifier must be of type `TestApp.B' or derived from it
Добавлено через 1 минуту
C# 3.0 spec is section 3.5.3:

When a protected instance member is accessed outside the program text of the class in which it is declared, and when a protected internal instance member is accessed outside the program text of the program in which it is declared, the access must take place within a class declaration that derives from the class in which it is declared. Furthermore, the access is required to take place through an instance of that derived class type or a class type constructed from it. This restriction prevents one derived class from accessing protected members of other derived classes, even when the members are inherited from the same base class.
кстати тут и объяснение в последней строчке, почему было решено так сделать.
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
24.07.2014, 10:29     Невозможно обратиться к protected член, объявленному в классе "Counter" #25
DrOffset, Да, спасибо. Вчера вечером и сам пришел к такому выводу, но написать уже возможности не было.
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
24.07.2014, 15:49     Невозможно обратиться к protected член, объявленному в классе "Counter" #26
Цитата Сообщение от HighPredator Посмотреть сообщение
А конструкторы не наследуются, значит данный пункт не работает.
Переносим конструктор в публичный раздел и всё компилируется. Тогда при чём здесь наследование конструкторов?
HighPredator
 Аватар для HighPredator
5351 / 1734 / 320
Регистрация: 10.12.2010
Сообщений: 5,120
Записей в блоге: 3
24.07.2014, 15:51     Невозможно обратиться к protected член, объявленному в классе "Counter" #27
Цитата Сообщение от alsav22 Посмотреть сообщение
Переносим конструктор в публичный раздел и всё компилируется. Тогда при чём здесь наследование конструкторов?
Не понял суть вопроса.
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
24.07.2014, 15:54     Невозможно обратиться к protected член, объявленному в классе "Counter" #28
А я вот это не понял:
Цитата Сообщение от HighPredator Посмотреть сообщение
Короче, в моем понимании на текущий момент, оно не компилируется потому что сие идет вразрез с пунктом 11.2 стандарта
Цитата Сообщение от HighPredator Посмотреть сообщение
. Нас интересует выделенное жирным. А конструкторы не наследуются, значит данный пункт не работает.
При чём здесь ошибка при компиляции кода и наследование конструкторов? Как нсчёт кода в 20 посте? Там уже не с конструктором.
HighPredator
 Аватар для HighPredator
5351 / 1734 / 320
Регистрация: 10.12.2010
Сообщений: 5,120
Записей в блоге: 3
24.07.2014, 16:26     Невозможно обратиться к protected член, объявленному в классе "Counter" #29
Цитата Сообщение от alsav22 Посмотреть сообщение
При чём здесь ошибка при компиляции кода и наследование конструкторов?
А, так понял. Оно имеет отношение к изначальному коду ТС, по которому он вызывает конструктор как явно пронаследованный метод.

Добавлено через 17 минут
Как оказалось, в такой ситуации реально проделегировать
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
typedef unsigned int uint;                                                                            
class Counter
{
protected:
    uint count;
    Counter() : count(0)
    { }
    Counter(int c) : count(c)
    { cout<<"in base";}
public:
    uint get_count () const
    { return count; }
    Counter operator++()
    { return Counter(++count); }
};
 
class CountDn : public Counter
{
public:
    CountDn(int c):Counter(c){};
    Counter operator--()
    { return CountDn(--count); } //нет еррора:) и сообщение будет:)
};
DrOffset
6458 / 3832 / 885
Регистрация: 30.01.2014
Сообщений: 6,627
24.07.2014, 18:57     Невозможно обратиться к protected член, объявленному в классе "Counter" #30
Цитата Сообщение от Psilon Посмотреть сообщение
бредовое поведение. В том же шарпе наследник может спокойно обращаться к полям базового класса, например:
Ну вот что за спешка? Твой пример работает и в С++. Мой пример - другой, смотри внимательней

Цитата Сообщение от Psilon Посмотреть сообщение
хм, а так - нельзя. Любопытно
Если бы ты внимательно посмотрел мой пример, то заметил бы, что он об этом же

Добавлено через 6 минут
Цитата Сообщение от HighPredator Посмотреть сообщение
нет еррора и сообщение будет
Ну так логично. Мы же создаем объект того же класса, что и текущий. А у него карт-бланш на доступ. Поэтому-то, кстати, пример Psilon не дает ошибки, а мой дает. Чужой класс - нет доступа.

В общем-то мне не очень понятно смущение многих в этой ветке по этому вопросу.
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
24.07.2014, 19:12     Невозможно обратиться к protected член, объявленному в классе "Counter" #31
Цитата Сообщение от DrOffset Посмотреть сообщение
Чужой класс - нет доступа.
Базовый класс для наследника разве можно назвать чужим? А наследник для базового - чужой. Вот это всё и смущает.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
24.07.2014, 19:21     Невозможно обратиться к protected член, объявленному в классе "Counter"
Еще ссылки по теме:

C++ Error C2440: <function-style-cast>: невозможно преобразовать "unsigned int" в "std::bitset<_Bits>"
C++ Error C2664: RegisterClassW: невозможно преобразовать параметр 1 из "WNDCLASSEX *" в "const WNDCLASSW *"
Error C2440: =: невозможно преобразовать "void *" в "Node *" C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
DrOffset
6458 / 3832 / 885
Регистрация: 30.01.2014
Сообщений: 6,627
24.07.2014, 19:21     Невозможно обратиться к protected член, объявленному в классе "Counter" #32
Цитата Сообщение от alsav22 Посмотреть сообщение
Базовый класс для наследника разве можно назвать чужим? Вот это и смущает
Ну тут разрешается логическое противоречие. С одной стороны protected доступ не разрешается для внешних сущностей. С другой стороны, мы наследуемся от класса с protected полями. Вот поэтому-то доступ может быть осуществлен только через указатель (this тоже относится) или ссылку на класс наследника. protected подразумевает, что мы проделегировали права доступа к защищенным полям через экземпляр текущего класса (наследника). Как только мы теряем тип (меняем например на базовый), то эти правила перестают работать, точно так же, как они перестают работать при обычном внешнем доступе. Иначе получилось бы, что одна и та же запись (обращение к полю через указатель на базовый класс) совершенно по-разному себя ведет в зависимости от того находится ли она внутри метода класса или снаружи. Если принять, что конструктор это функция, пусть и специальная, то легко можно представить, что для нее работают все те же правила, что и для других функций и переменных. Делать в этом случае какое-то исключение было бы неправильно.
Yandex
Объявления
24.07.2014, 19:21     Невозможно обратиться к protected член, объявленному в классе "Counter"
Ответ Создать тему
Опции темы

Текущее время: 03:24. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru