Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.57/30: Рейтинг темы: голосов - 30, средняя оценка - 4.57
36 / 29 / 2
Регистрация: 01.08.2011
Сообщений: 176
1

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

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

Author24 — интернет-сервис помощи студентам
Всем привет! Начал писать одну программку, и столкнулся со следующей проблемой: у меня пока 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
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
11.10.2011, 22:52
Ответы с готовыми решениями:

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

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

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

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

11
5231 / 3204 / 362
Регистрация: 12.12.2009
Сообщений: 8,116
Записей в блоге: 2
12.10.2011, 04:35 2
Как наследуешь?
0
Делаю внезапно и красиво
Эксперт С++
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
12.10.2011, 08:00 3
C++
1
class Vector : MemObject {...};
Ты ведь так унаследовал, да?
0
36 / 29 / 2
Регистрация: 01.08.2011
Сообщений: 176
12.10.2011, 14:02  [ТС] 4
Вот так:
C++
1
2
3
4
#include "MemObject.h"
 
class Vector: public MemObject
{
0
Делаю внезапно и красиво
Эксперт С++
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
12.10.2011, 14:09 5
Попробуй не называть локальные переменные, как данные-члены класса. Чтобы вот такое не писать this->memUse=memUse.
0
36 / 29 / 2
Регистрация: 01.08.2011
Сообщений: 176
12.10.2011, 14:19  [ТС] 6
Цитата Сообщение от Deviaphan Посмотреть сообщение
Попробуй не называть локальные переменные, как данные-члены класса. Чтобы вот такое не писать this->memUse=memUse.
А разве это поможет?

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

Добавлено через 2 минуты
Ааааа, так ты про ошибку в строке 9. Классы Vector и MemObject это разные классы, поэтому из объекта Vector нельзя получить доступ к закрытым полям класса MemObject.
0
36 / 29 / 2
Регистрация: 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
5231 / 3204 / 362
Регистрация: 12.12.2009
Сообщений: 8,116
Записей в блоге: 2
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
36 / 29 / 2
Регистрация: 01.08.2011
Сообщений: 176
12.10.2011, 18:30  [ТС] 10
Как-то не очень удобно сделано. И как можно получить доступ к защищённым полям класса, если невозможно обращаться к ним через this? Я думаю нужно использовать дружественые классы, но тогда нужно при создании каждого нового потомка добавлять его в список дружественных классов. А может есть другие способы?
0
Делаю внезапно и красиво
Эксперт С++
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
12.10.2011, 18:36 11
Цитата Сообщение от Виктор_Сен Посмотреть сообщение
И как можно получить доступ к защищённым полям класса, если невозможно обращаться к ним через this?
Используя методы доступа. Или friend.
0
36 / 29 / 2
Регистрация: 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
13.10.2011, 00:28
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
13.10.2011, 00:28
Помогаю со студенческими работами здесь

Переопределенные операторы в дочернем классе
Всем привет! В общем, столкнулся с проблемой. У меня есть базовый класс в котором переопределены...

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

Использование переменных базового класса в дочернем классе
Доброго времени суток. Подскажите пожалуйста как в классе SumbString работать с переменными(string...

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


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

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru