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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 13, средняя оценка - 4.92
stzer
89 / 65 / 19
Регистрация: 26.10.2013
Сообщений: 201
Завершенные тесты: 2
#1

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

23.07.2014, 16:07. Просмотров 1782. Ответов 31
Метки нет (Все метки)

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"
Посмотрите здесь:
C++ Невозможно обратиться к private член, объявленному в классе "Complex"
C++ Невозможно обратиться к private член, объявленному в классе
C++ базовый и производный класс, в базовом объявлена переменная "protected", она недоступна по имени в производном классе! template <class T> воду мутит!
В пользовательском классе "Матрица" реализовать функцию-член для вычисления определителя C++
бинарный "++": "Counter" не определяет этот оператор или преобразование к типу приемлемо к встроенному C++
Ошибка при сборке многофайлового проекта: "невозможно преобразовать "int" в "const golf" C++
Error C2440: инициализация: невозможно преобразовать "void *" в "listnode *". подскажите, что можно сделать? C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Psilon
Master of Orion
Эксперт .NET
5846 / 4743 / 628
Регистрация: 10.07.2011
Сообщений: 14,282
Записей в блоге: 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
5416 / 4812 / 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
5464 / 1830 / 338
Регистрация: 10.12.2010
Сообщений: 5,410
Записей в блоге: 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
Эксперт .NET
5846 / 4743 / 628
Регистрация: 10.07.2011
Сообщений: 14,282
Записей в блоге: 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
В астрале
Эксперт С++
7967 / 4729 / 320
Регистрация: 24.06.2010
Сообщений: 10,539
Завершенные тесты: 3
24.07.2014, 10:29     Невозможно обратиться к protected член, объявленному в классе "Counter" #25
DrOffset, Да, спасибо. Вчера вечером и сам пришел к такому выводу, но написать уже возможности не было.
alsav22
5416 / 4812 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
24.07.2014, 15:49     Невозможно обратиться к protected член, объявленному в классе "Counter" #26
Цитата Сообщение от HighPredator Посмотреть сообщение
А конструкторы не наследуются, значит данный пункт не работает.
Переносим конструктор в публичный раздел и всё компилируется. Тогда при чём здесь наследование конструкторов?
HighPredator
5464 / 1830 / 338
Регистрация: 10.12.2010
Сообщений: 5,410
Записей в блоге: 3
24.07.2014, 15:51     Невозможно обратиться к protected член, объявленному в классе "Counter" #27
Цитата Сообщение от alsav22 Посмотреть сообщение
Переносим конструктор в публичный раздел и всё компилируется. Тогда при чём здесь наследование конструкторов?
Не понял суть вопроса.
alsav22
5416 / 4812 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
24.07.2014, 15:54     Невозможно обратиться к protected член, объявленному в классе "Counter" #28
А я вот это не понял:
Цитата Сообщение от HighPredator Посмотреть сообщение
Короче, в моем понимании на текущий момент, оно не компилируется потому что сие идет вразрез с пунктом 11.2 стандарта
Цитата Сообщение от HighPredator Посмотреть сообщение
. Нас интересует выделенное жирным. А конструкторы не наследуются, значит данный пункт не работает.
При чём здесь ошибка при компиляции кода и наследование конструкторов? Как нсчёт кода в 20 посте? Там уже не с конструктором.
HighPredator
5464 / 1830 / 338
Регистрация: 10.12.2010
Сообщений: 5,410
Записей в блоге: 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
6909 / 4102 / 933
Регистрация: 30.01.2014
Сообщений: 6,893
24.07.2014, 18:57     Невозможно обратиться к protected член, объявленному в классе "Counter" #30
Цитата Сообщение от Psilon Посмотреть сообщение
бредовое поведение. В том же шарпе наследник может спокойно обращаться к полям базового класса, например:
Ну вот что за спешка? Твой пример работает и в С++. Мой пример - другой, смотри внимательней

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

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

В общем-то мне не очень понятно смущение многих в этой ветке по этому вопросу.
alsav22
5416 / 4812 / 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"
Еще ссылки по теме:
error C2664: CWnd::MessageBoxW: невозможно преобразовать параметр 2 из "long" в "LPCTSTR" C++
C++ Error C2664: RegisterClassW: невозможно преобразовать параметр 1 из "WNDCLASSEX *" в "const WNDCLASSW *"
C++ Error C2440: <function-style-cast>: невозможно преобразовать "unsigned int" в "std::bitset<_Bits>"
C++ Невозможно преобразовать "unsigned int" в "output::book_origin"
невозможно преобразовать параметр 1 из "const char [8]" в "LPCWSTR" C++

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

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

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru