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

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

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 19, средняя оценка - 4.74
Виктор_Сен
33 / 26 / 1
Регистрация: 01.08.2011
Сообщений: 176
#1

Не могу в дочернем классе вызвать protected метод - C++

11.10.2011, 22:52. Просмотров 2570. Ответов 11
Метки нет (Все метки)

Всем привет! Начал писать одну программку, и столкнулся со следующей проблемой: у меня пока 2 класса: MemObject и Vector, где Vector наследует свойства MemObject. Так вот, в классе MemObject есть чисто виртуальный метод _detectMemUse, который вычистляет память, занимаемую объектом MemObject. Фишка в том, что объект класса Vector должен уметь содержать любые объекты класса MemObject, даже ещё неизвестные. Частью этого плана является то, что при вызове метода _detectMemUse для текущего вектора нужно вызвать этот метод для всех внутренних MemObject-ов, причём в зависимости от реального типа внутреннего объекта будет вызываться свой _detectMemUse. Вот с этим вызовом и возникла продлема. Вот фрагмент кода класса Vector:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
i8 Vector::_detectMemUse(bool isUpdateMemUse)
{
    i8 memUse=microDetectMemUse();
    if (type==MEM_OBJECT)
    {
        MemObject **tmpObj=(MemObject **)data;
        for (i8 i=0; i<cellsCount; i++)
        {
            if (*tmpObj) memUse+=(**tmpObj)._detectMemUse(isUpdateMemUse);
            tmpObj++;
        }
    }
    if (isUpdateMemUse) this->memUse=memUse;    
    return memUse;
}
А вот фрагмент класса MemObject:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public:
 
    typedef void (*MemControlPointer)(i8,i8);   
    typedef void (*MemErrorPointer)(i8,i8);
 
protected:
 
    //Учёт памяти
    MemControlPointer memControl;
    i8 memUse;
    bool isBlockedMemControl;
    i8 currElemNum;
    virtual void setIsBlockedMemControl(bool val)=0;
    virtual i8 _detectMemUse(bool isUpdateMemUse)=0;
 
    //Ошибка выделения памяти
    MemErrorPointer memError;
Вот что выдаёт компилятор: "error C2248: MemObject::_detectMemUse: невозможно обратиться к protected член, объявленному в классе "MemObject" D:\doc\dev\Visual Studio 2010\VectorTest\VectorTest\Vector.cpp". Так почему я не могу обратиться к protected методу?
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
11.10.2011, 22:52
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Не могу в дочернем классе вызвать protected метод (C++):

Как обьявить переменную в одном классе и что бы ее было видно в дочернем классе - C++
У меня есть основной класс с названием Root один из его членов наследует дочерний класс SubRoot. Скажите как объявить, что бы один из...

Вызвать метод класса в другом классе - C++
Подскажите как мне вызвать метод класса в другом классе ?

Ошибка в дочернем классе - C++
Не могу найти ошибку в дочернем классе, возможно не правильно написать main Задание и код: Код нужно переписывать в сообщение Только...

Перегрузка fstream в дочернем классе - C++
h class Child:public StudentsBD{ friend fstream &amp;operator&lt;&lt;( fstream&amp; , string &amp; ); friend fstream &amp;operator&gt;&gt;( fstream&amp; , string...

Как в классе А у объекта класса B вызвать метод класса B ? - C++
Есть Класс A и класс B . В классе B лежит объект типа ArrayList , назовём его arrayList, в этом же классе есть метод push() . Возможно ли в...

Изменение информации в дочернем классе, через ссылку - C++
Подскажите, есть класс class Class1 В конструкторе я создаю структуру, которая будет хранить в себе ссылки на все классы...

11
Kastaneda
Форумчанин
Эксперт С++
4655 / 2863 / 228
Регистрация: 12.12.2009
Сообщений: 7,275
Записей в блоге: 2
Завершенные тесты: 1
12.10.2011, 04:35 #2
Как наследуешь?
0
Deviaphan
Делаю внезапно и красиво
Эксперт С++
1305 / 1220 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
12.10.2011, 08:00 #3
C++
1
class Vector : MemObject {...};
Ты ведь так унаследовал, да?
0
Виктор_Сен
33 / 26 / 1
Регистрация: 01.08.2011
Сообщений: 176
12.10.2011, 14:02  [ТС] #4
Вот так:
C++
1
2
3
4
#include "MemObject.h"
 
class Vector: public MemObject
{
0
Deviaphan
Делаю внезапно и красиво
Эксперт С++
1305 / 1220 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
12.10.2011, 14:09 #5
Попробуй не называть локальные переменные, как данные-члены класса. Чтобы вот такое не писать this->memUse=memUse.
0
Виктор_Сен
33 / 26 / 1
Регистрация: 01.08.2011
Сообщений: 176
12.10.2011, 14:19  [ТС] #6
Цитата Сообщение от Deviaphan Посмотреть сообщение
Попробуй не называть локальные переменные, как данные-члены класса. Чтобы вот такое не писать this->memUse=memUse.
А разве это поможет?

Добавлено через 2 минуты
Для интереса попробовал. Не помогло.
0
Deviaphan
Делаю внезапно и красиво
Эксперт С++
1305 / 1220 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
12.10.2011, 14:21 #7
По крайней мере, код станет читабельным.

Добавлено через 2 минуты
Ааааа, так ты про ошибку в строке 9. Классы Vector и MemObject это разные классы, поэтому из объекта Vector нельзя получить доступ к закрытым полям класса MemObject.
0
Виктор_Сен
33 / 26 / 1
Регистрация: 01.08.2011
Сообщений: 176
12.10.2011, 14:30  [ТС] #8
Да, в строке 9
C++
1
if (*tmpObj) memUse+=(**tmpObj)._detectMemUse(isUpdateMemUse);
Но ведь метод _detectMemUse класса MemObject объявлен как protected, а
C++
1
class Vector: public MemObject
. То есть по-идее из класса Vector должен быть доступ к protected методам родителя. Я понимаю, если бы было private...
0
Kastaneda
Форумчанин
Эксперт С++
4655 / 2863 / 228
Регистрация: 12.12.2009
Сообщений: 7,275
Записей в блоге: 2
Завершенные тесты: 1
12.10.2011, 14:50 #9
Тут такое дело - если б ты вызвал _detectMemUse() для this, т.е.
C++
1
memUse+=this->_detectMemUse(isUpdateMemUse);
то все было бы нормально, _detectMemUse() был бы в области видимости, но поскольку ты вызываешь ее для стороннего объекта, то _detectMemUse получается private.

Добавлено через 3 минуты
пример:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class A{
protected:
    int x;
public:
    A():x(10){}
};
 
class B : public A{
    //A a;
public:
    void f(){
        std::cout<<x<<" "
                       //<< a.x
                         <<std::endl;
    }
};
    
int main(){
 B b;
 b.f();
 return 0;
}
если раскоментировать закоментированные строки, код становиться некомпилируемым.
2
Виктор_Сен
33 / 26 / 1
Регистрация: 01.08.2011
Сообщений: 176
12.10.2011, 18:30  [ТС] #10
Как-то не очень удобно сделано. И как можно получить доступ к защищённым полям класса, если невозможно обращаться к ним через this? Я думаю нужно использовать дружественые классы, но тогда нужно при создании каждого нового потомка добавлять его в список дружественных классов. А может есть другие способы?
0
Deviaphan
Делаю внезапно и красиво
Эксперт С++
1305 / 1220 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
12.10.2011, 18:36 #11
Цитата Сообщение от Виктор_Сен Посмотреть сообщение
И как можно получить доступ к защищённым полям класса, если невозможно обращаться к ним через this?
Используя методы доступа. Или friend.
0
Виктор_Сен
33 / 26 / 1
Регистрация: 01.08.2011
Сообщений: 176
13.10.2011, 00:28  [ТС] #12
А если, например, создать в классе MemObject метод callDetectMemUse, который будет получать указатель на объект MemObject и возвращать результат _detectMemUse, но уже вызванный для этого объекта, и вызывать callDetectMemUse через this. Тогда произойдёт "плавный" вызов нужного метода от имени класса MemObject. Вот что у меня получилось (_detectMemUse я переименовал в insideDetectMemUse, чтоб не путаться, поскольку detectMemUse у меня в этом классе тоже есть): MemObject.h:
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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#pragma once
 
class MemObject
{
 
public:
 
    //Указатель на функцию контроля памяти
    //(вызывается при {выделении/освобождении} памяти)
    //Параметры: размер блока памяти и номер объекта, 
    //{захватившего/освободившего} память
    //Функция позволяет вызывать механизм 
    //{сохранения/загрузки} данных {на диск/с диска} при 
    //{нехватке/достаточном количестве} памяти
    typedef void (*MemControlPointer)(i8,i8);   
 
    //Указатель на функцию, 
    //вызываемую при перехвате исключений, 
    //генерируемых при выделении памяти
    //Параметры: размер блока памяти, 
    //при выделении которого призошла ошибка
    //и номер объекта-источника исключения
    typedef void (*MemErrorPointer)(i8,i8);
 
protected:
 
    //Указатель на функцию контроля памяти и 
    //флаг блокировки этого контроля
    MemControlPointer memControl;
    bool isBlockedMemControl;
 
    //Используемая обектом память
    i8 memUse;
    
    //Номер текущего объекта для функции
    //{контроля/ошибки} памяти
    i8 currElemNum;
 
    //Функция изменения флага блокировки контроля памяти
    //Вызывается рекурсивно для всех внутренних объектов
    virtual void setIsBlockedMemControl(bool val)=0;
 
    //Подсчитывает занимаемую объектом память, и,
    //в зависимости от флага isUpdateMemUse,
    //обновляет значение поля memUse
    virtual i8 insideDetectMemUse(bool isUpdateMemUse)=0;
 
    //Получает указатель на MemObject и 
    //вызывает insideDetectMemUse от его имени
    i8 callInsideDetectMemUse(bool isUpdateMemUse, MemObject *memObj);
 
    //Получает указатель на MemObject и 
    //вызывает setIsBlockedMemControl от его имени
    void callSetIsBlockedMemControl(bool val, MemObject *memObj);
 
    //Указатель на функцию, вызываемую при
    //ошибке выделения памяти
    MemErrorPointer memError;
 
public:
 
    //Деструктор
    //Вызывает memControl(-memUse,currElemNum),
    //если флаг isBlockedMemControl==false
    //Поэтому при удалении дочернего объекта
    //не нужно заботиться об учёте факта 
    //освобождения памяти
    virtual ~MemObject(void);
 
    //Конструктор
    MemObject(
        MemControlPointer memControl,
        bool isBlockedMemControl,       
        i8 currElemNum,     
        MemErrorPointer memError);
    
    //Обёртка insideDetectMemUse,
    //которая вызывает insideDetectMemUse
    //с параметром false
    //Это нужно, чтобы пользователь класса
    //не мог изменять поле memUse,
    //например, если поле memUse хранит
    //не всю память, а только память,
    //занимаемую текущим объектом без учёта
    //внутренних объектов
    i8 detectMemUse();
 
    //Доступ к полям
    MemControlPointer getMemControl();
    bool getIsBlockedMemControl();
    i8 getMemUse();         
    i8 getCurrElemNum();
    MemErrorPointer getMemError();
 
};
Фрагмент кода Vector.cpp:
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
//Вычисление занимаемой объектом памяти
//Параметр - флаг обновления текущего значения используемой памяти
//Возвращаемое значение - занимаемая память
i8 Vector::insideDetectMemUse(bool isUpdateMemUse)
{
    //Подсчёт памяти без учёта внутренних объектов
    i8 currMemUse=microDetectMemUse();
 
    //Если есть внутренние объекты
    if (type==MEM_OBJECT)
    {
        MemObject **tmpObj=(MemObject **)data;
        for (i8 i=0; i<cellsCount; i++)
        {
            //Если ссылка на внутренний объект не нулевая, то вызов
            //вычислителя памяти для внутреннего объекта
            if (*tmpObj) currMemUse+=
                callInsideDetectMemUse(isUpdateMemUse,*tmpObj);                         
            tmpObj++;
        }
    }
 
    //Обновление поля занимаемой памяти
    if (isUpdateMemUse) memUse=currMemUse;  
 
    return currMemUse;
}
Сработало)))

Добавлено через 7 минут
В сторке 50 MemObject.h искомая функция-обёртка для insideDetectMemUse, а в сторке 18 Vector.cpp её вызов.
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
13.10.2011, 00:28
Привет! Вот еще темы с ответами:

Использование переменных базового класса в дочернем классе - C++
Доброго времени суток. Подскажите пожалуйста как в классе SumbString работать с переменными(string s;int z ; ) класса factory ? Мне...

Можно ли как-то в дочернем классе получить указатель родителя? - C++
У меня тут появилась мыслишка :D В любом классе есть так сказать скрытый указатель на самого себя - this, а можно ли как то получить в...

R6025 pure virtual function call при вызове метода, реализованного в дочернем классе - C++
Всем привет. Вот такая ошибка у меня возникает при вызове метода, который реализован в дочернем классе, но потом он почему-то становится...

У меня класс B в классе A, а в классе B рекурсивная функция переопределения оператора "()", как её вызвать, не создавая явно объект класса B? - C++
#include &lt;windows.h&gt; #include &lt;iostream&gt; using namespace std; //Вот главный класс class A{ public: A (){}; class...


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

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

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