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

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

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

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

23.07.2014, 16:07. Просмотров 1848. Ответов 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++
выдавало ошибку &quot;невозможно обратиться к private член, объявленному в классе &quot;Complex&quot;&quot; я поменяла int n; private: double re; ...

Невозможно обратиться к private член, объявленному в классе - C++
View.h #pragma once #include &quot;Model.h&quot; class View { private: ModelClass model; public: View(ModelClass...

базовый и производный класс, в базовом объявлена переменная "protected", она недоступна по имени в производном классе! template <class T> воду мутит! - C++
Друзья! Вот код #include &lt;stdio.h&gt; template &lt;class T&gt; class otets { protected: int peremennaya; }; template &lt;class...

В пользовательском классе "Матрица" реализовать функцию-член для вычисления определителя - C++
Прива всем. Такой вопрос. Написал класс &quot;Матрица&quot;. Хочу добавить метод для вычисления определителя. Написал функцию (&quot;не для класса&quot;)...

бинарный "++": "Counter" не определяет этот оператор или преобразование к типу приемлемо к встроенному - C++
бинарный &quot;++&quot;: &quot;Counter&quot; не определяет этот оператор или преобразование к типу приемлемо к встроенному оператору #include &lt;iostream&gt; ...

Ошибка при сборке многофайлового проекта: "невозможно преобразовать "int" в "const golf" - C++
Сделал многофайловую программу программу, вот она: //golf.h #include &lt;iostream&gt; #ifndef golg_h_ #define golf_h_ const int Len =...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
ValeryS
Модератор
6556 / 5022 / 464
Регистрация: 14.02.2011
Сообщений: 16,763
23.07.2014, 18:38 #16
Цитата Сообщение от stzer Посмотреть сообщение
И вообще я читал везде, что статический метод используется для обращения только к стат-ким полям класса.
Он может обращаться к любым членам
просто в него не передается неявный параметр this, в отличии от нестатических методов
следовательно его нужно явно передать
например
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class A
{
public:
int i;
staic void StatFunc(int b, A* a){a->i=b;); 
 
 
} 
int main()
{
A a;
A::StatFunc(10,&a);
 
}
stzer
92 / 68 / 20
Регистрация: 26.10.2013
Сообщений: 204
Завершенные тесты: 2
23.07.2014, 19:00  [ТС] #17
ValeryS, Спасибо, интересно
DrOffset
7089 / 4230 / 950
Регистрация: 30.01.2014
Сообщений: 7,006
23.07.2014, 19:23 #18
Цитата Сообщение от ForEveR Посмотреть сообщение
почему это я не могу создать объект базового класса просто так, а не как часть данного (в конструкторе)?
Да можешь запросто, например из friend функции. Из нее можно и с private.

Добавлено через 7 минут
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class A
{
public:
    friend A create();
 
protected:
    A(int a) : a(a) { }
private:
    int a;
};
 
A create()
{
    return A(10);
}
 
int main()
{
    A a = create();
}
Это абсолютно легально.
Полезно при проектировании фабричных классов. Создаваемые классы защищены от создания вне фабрики (protected конструктор), но в то же время их можно расширять путем наследования.
alsav22
5417 / 4813 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
23.07.2014, 19:54 #19
Цитата Сообщение от DrOffset Посмотреть сообщение
Да можешь запросто, например из friend функции. Из нее можно и с private.
Вопрос остался: почему в методе производного класса нельзя вызвать защищённый конструктор базового?
DrOffset
7089 / 4230 / 950
Регистрация: 30.01.2014
Сообщений: 7,006
23.07.2014, 20:35 #20
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от alsav22 Посмотреть сообщение
Вопрос остался: почему в методе производного класса нельзя вызвать защищённый конструктор базового?
А вот в чем вопрос-то. Я сразу не понял
В общем, protected просто так работает. Он предоставляет доступ к "закрытым" полям базового класса только для объекта наследника. Вот небольшой пример:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class A
{
protected:
    int a;
};
 
class B : public A
{
public:
    B()
    {
         a = 1; // ок. мы в том же самом объекте
         A * p = this;
         p->a = 0; //ошибка
    }
};
Конструирование класса А тоже к этому относится. Т.к. конструктор вызывается уж не у текущего объекта.
Ссылку на стандарт попробую попозже найти.

Добавлено через 9 минут
Собственно вот (о чем я и говорил см. Clause 11):
12/4
Special member functions obey the usual access rules (Clause 11). [ Example: declaring a constructor
protected ensures that only derived classes and friends can create objects using it
. —end example ]
Как раз привели в пример конкретную ситуацию с конструктором.
Psilon
Master of Orion
Эксперт .NET
5887 / 4784 / 633
Регистрация: 10.07.2011
Сообщений: 14,405
Записей в блоге: 5
Завершенные тесты: 4
24.07.2014, 02:13 #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
5417 / 4813 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
24.07.2014, 02:37 #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
5477 / 1843 / 343
Регистрация: 10.12.2010
Сообщений: 5,435
Записей в блоге: 3
24.07.2014, 08:13 #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
5887 / 4784 / 633
Регистрация: 10.07.2011
Сообщений: 14,405
Записей в блоге: 5
Завершенные тесты: 4
24.07.2014, 09:48 #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
В астрале
Эксперт С++
7970 / 4732 / 321
Регистрация: 24.06.2010
Сообщений: 10,541
Завершенные тесты: 3
24.07.2014, 10:29 #25
DrOffset, Да, спасибо. Вчера вечером и сам пришел к такому выводу, но написать уже возможности не было.
alsav22
5417 / 4813 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
24.07.2014, 15:49 #26
Цитата Сообщение от HighPredator Посмотреть сообщение
А конструкторы не наследуются, значит данный пункт не работает.
Переносим конструктор в публичный раздел и всё компилируется. Тогда при чём здесь наследование конструкторов?
HighPredator
5477 / 1843 / 343
Регистрация: 10.12.2010
Сообщений: 5,435
Записей в блоге: 3
24.07.2014, 15:51 #27
Цитата Сообщение от alsav22 Посмотреть сообщение
Переносим конструктор в публичный раздел и всё компилируется. Тогда при чём здесь наследование конструкторов?
Не понял суть вопроса.
alsav22
5417 / 4813 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
24.07.2014, 15:54 #28
А я вот это не понял:
Цитата Сообщение от HighPredator Посмотреть сообщение
Короче, в моем понимании на текущий момент, оно не компилируется потому что сие идет вразрез с пунктом 11.2 стандарта
Цитата Сообщение от HighPredator Посмотреть сообщение
. Нас интересует выделенное жирным. А конструкторы не наследуются, значит данный пункт не работает.
При чём здесь ошибка при компиляции кода и наследование конструкторов? Как нсчёт кода в 20 посте? Там уже не с конструктором.
HighPredator
5477 / 1843 / 343
Регистрация: 10.12.2010
Сообщений: 5,435
Записей в блоге: 3
24.07.2014, 16:26 #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
7089 / 4230 / 950
Регистрация: 30.01.2014
Сообщений: 7,006
24.07.2014, 18:57 #30
Цитата Сообщение от Psilon Посмотреть сообщение
бредовое поведение. В том же шарпе наследник может спокойно обращаться к полям базового класса, например:
Ну вот что за спешка? Твой пример работает и в С++. Мой пример - другой, смотри внимательней

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

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

В общем-то мне не очень понятно смущение многих в этой ветке по этому вопросу.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
24.07.2014, 18:57
Привет! Вот еще темы с ответами:

Где ошибка невозможно преобразовать указатель "this" из "const pers" в "pers &" при выводе объектов через cout - C++
Добрый день! Переписал код из книг Лафоре, создание мультимножества из собственных объектов- справочник телефонный, с именем и фамилией. ...

Error C2440: инициализация: невозможно преобразовать "void *" в "listnode *". подскажите, что можно сделать? - C++
#include &lt;iostream&gt; struct listnode { char *data; int value; struct listnode *next; }; struct listnode...

error C2664: CWnd::MessageBoxW: невозможно преобразовать параметр 2 из "long" в "LPCTSTR" - C++
при компиляции выдаёт ошибку указанную в теме, код: void Clab_12_2Dlg::OnClickedAri() { // TODO: добавьте свой код обработчика...

Error C2664: RegisterClassW: невозможно преобразовать параметр 1 из "WNDCLASSEX *" в "const WNDCLASSW *" - C++
почему выдаёт ошибку? int RegClass(WNDPROC Proc,LPCTSTR szName,UINT brBackground){ WNDCLASSEX wc; ...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
24.07.2014, 18:57
Ответ Создать тему
Опции темы

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