Модераторы: bsa

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Нет доступа к Protected полям БАЗОВОГО класса 
:(
    Опции темы
PashaLost
Дата 14.10.2011, 00:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 36
Регистрация: 18.1.2008

Репутация: нет
Всего: нет



Попробую описать подробно: 

Задача: 
/* Домашние электроприборы
Определить иерархию электроприборов. Включить некоторые в розетку. Посчитать потребляемую мощность. Провести сортировку приборов в квартире на основе одного из параметров. Найти прибор в квартире, соответствующий заданному диапазону параметров */

Мой вариант решения: 
                                               Класс Electricity(базовый)
Класс Network :public Electricity                              Класс Device:public Electricity
                                                                                Класс DeviceList: public Device
В классах Network в DeviceList все функции статические и не создаётся никаких объектов. 
В классе DeviceList есть массив указателей на класс Device. Объекты класса Device создаются динамически.

Проблема: у статических функций класса DeviceList НЕТ доступа к protected полям класса Device
и поэтому приходится использовать функции get... 

Компилятор: error C2248: Device::name: невозможно обратиться к protected член, объявленному в классе "Device"

Код

class Device: public Electricity {            
public:    
    Device(const char *, int, int, int);           // конструктор
    ~Device();    

    void TurnOn();        // функции вызываются из класса deviceList
    void TurnOff();        // их нужно перенести в Protected, но  компилятор выдаёт ошибку
    
    char* getName();        //    функции по сути не нужны
    int getSelfPower();        //    доступ к полям должен быть у класса deviceList
    int getCost();            //    но его почему-то нет
    int getUseful();                    
    int getRealTimePower();                
protected:                                         
    char *name;                // название электроприбора
    int selfPower;                // техническая мощность прибора
    int cost;                    // цена
    int useful;                    // польза 
    int realTimePower;            // потребляемая мощность прибора на текущий момент
};
    
class DeviceList: public Device {            
public:    
    void function();            // пробная функция, у которой тоже нет доступа к полям Device
    static void DeleteDeviceList();                    // искусственный деструктор
    static void newDevice(const char*, int, int, int);    // функция вызывает конструктор Device 

    static void TurnOn(char *);                    // функции вызывают TurnOn/Off в классе Device
    static void TurnOff(char *);

    static void SortByPower();                // сортировки
    static void SortByCost();
    static void SortByUseful();

    static void FindByPower(int, int);            // поиск
    static void FindByCost(int, int);
    static void FindByUseful(int, int);

    static int getDeviceCounter();                // нужна для класса Electricity
    static Device* getDevicePtr(int);            // тоже 
    static void printList();
protected:
    static Device *devicePtr[100];                // массив указателей на класс Device
    static int deviceCounter;                    // счётчик электроприборов
};

DeviceList.cpp (не все функции - места жалко )

// пробная функция, у которой ТОЖЕ нет доступа
void DeviceList::function() {
    cout << devicePtr[0]->name << endl; 
}

void DeviceList::newDevice(const char* a, int b, int c, int d) {
    devicePtr[deviceCounter]=new Device(a, b, c, d);
    assert(devicePtr[deviceCounter]!=0);
    deviceCounter++;
}    

void DeviceList::printList() {

    if (deviceCounter) {
        cout << "Список электроприборов:" << endl;
        cout << "\t№ \tName \t\tPower \t\tCost $ \t\tUseful " << endl;
        for (int i=0; i<deviceCounter; i++) {
            cout << "\t" << i+1 
                << ":\t"  << devicePtr[i]->getName()                        // вот здесь и хотелось бы 
                << "\t\t" << devicePtr[i]->getSelfPower()                 // получить доступ напрямую
                << "\t\t" << devicePtr[i]->getCost()                          // а не через функции get
                << "\t\t" << devicePtr[i]->getUseful() << endl;
        }
    } else {cout << "Пока нет ни одного электроприбора" << endl; }
}




PM MAIL   Вверх
math64
Дата 14.10.2011, 08:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 12
Всего: 72



protected поля доступны только через this - по-моему, вполне логично. Даётся доступ только к protected полям только своего экземпляра базового класса.
Если нужен доступ к полям через произвольный указатель, объявите friend DeviceList в Device, нужно также предварительное объявление class DeviceList;
А лучше так:
Код

class Device: public Electricity {            
public:
    const char* getName() { return name; }
};
void DeviceList::function() {
    cout << devicePtr[0]->getName() << endl; 
}


PM   Вверх
borisbn
Дата 14.10.2011, 08:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 21
Всего: 135



1. Зачем класс СписокДевайсов наследован от класса Девайс ?
2. В статической (!!!) ф-ции printList() (читай просто функция, практически находящаяся в namespace DeviceList:: ) идёт обращение к статическому (!!!) массиву указателей на Device (читай просто массиву, НЕ ИМЕЮЩЕМУ ОТНОШЕНИЯ К DeviceList). Почему она должна иметь доступ к членам класса Device ?


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
Dem_max
Дата 14.10.2011, 09:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1780
Регистрация: 12.4.2007

Репутация: 4
Всего: 39



а зачем в DeviceList статические функции ???


--------------------
Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte")
PM MAIL   Вверх
azesmcar
Дата 14.10.2011, 09:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 52
Всего: 211



и вообще, protected переменные - зло smile 
PM   Вверх
PashaLost
Дата 14.10.2011, 12:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 36
Регистрация: 18.1.2008

Репутация: нет
Всего: нет



Цитата(borisbn @ 14.10.2011,  06:53)
1. Зачем класс СписокДевайсов наследован от класса Девайс ?



СписокДевайсов наследован от класса Девайс как раз с ТОЙ целью, чтобы иметь ДОСТУП к протектед полям Девайса, но раз уж доступ к ним могут иметь ТОЛЬКО экземпляры самого класса, тогда вся затея коту под хвост. Все функции статические только лишь для того, чтобы НЕ заводить объектов классов ДевайсЛист, Електричество и Нетворк. 
  Следуя только своей собственной логике не вижу смысла просто так создавать объекты, которые потом нигде не пригодятся. Сильно не ругайтесь, не забывайте в КАКОМ разделе форума задан вопрос
PM MAIL   Вверх
borisbn
Дата 14.10.2011, 12:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 21
Всего: 135



Цитата(PashaLost @  14.10.2011,  12:50 Найти цитируемый пост)
но раз уж доступ к ним могут иметь ТОЛЬКО экземпляры самого класса

или экземпляры класса наследника. в твоём же примере экземпляра класса наследника, т.е. ДевайсЛиста, не создаётся (т.к. и ф-ция printList() и массив devicePtr() статические, то они не принадлежат ни одному экземпляру класса ДевайсЛист)

Это сообщение отредактировал(а) borisbn - 14.10.2011, 12:58


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
mes
Дата 14.10.2011, 13:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(PashaLost @  14.10.2011,  11:50 Найти цитируемый пост)
Все функции статические только лишь для того, чтобы НЕ заводить объектов классов 

класс Devicelist в том виде в каком есть овообще лишняя сущность.. 
все это уже есть в языке :
http://www.cplusplus.com/reference/stl/
http://www.cplusplus.com/reference/algorithm/sort/
http://www.cplusplus.com/reference/algorithm/find_if/
и т.д. 




--------------------
PM MAIL WWW   Вверх
PashaLost
Дата 14.10.2011, 18:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 36
Регистрация: 18.1.2008

Репутация: нет
Всего: нет



да да да, я знаю, STL это круто,но в рамках задания была поставлена задача - обойтись без помощи СТЛ
PM MAIL   Вверх
mes
Дата 14.10.2011, 19:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(PashaLost @  14.10.2011,  17:58 Найти цитируемый пост)
да да да, я знаю, STL это круто,но в рамках задания была поставлена задача - обойтись без помощи СТЛ 

можно и без стл..  все равно перепроектировать не мешало бы..

Добавлено @ 19:18
Цитата(PashaLost @  13.10.2011,  23:16 Найти цитируемый пост)
  int getSelfPower();        //    доступ к полям должен быть у класса deviceList
    int getCost();            //    но его почему-то нет
    int getUseful();                    
    int getRealTimePower();  

вот например зачем столько гетеров ? да еще и не константных..

гораздо нагляднее было бы :
 
Код


struct DeviceSpecification
{
    int selfPower;                // техническая мощность прибора
    int cost;                    // цена
    int useful;                    // польза 
    int realTimePower;
};

class Device
{
   public:
     void Turn (bool ); // true = off , false = off
     DeviceSpecification  const& GetDeviceSpecification () const  { return _specification; }
 
  private:
     DeviceSpecification _specification;
};


Это сообщение отредактировал(а) mes - 14.10.2011, 19:48


--------------------
PM MAIL WWW   Вверх
math64
Дата 14.10.2011, 19:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 12
Всего: 72



Лучше так:
Код

const DeviceSpecification& GetDeviceSpecification () const  { return _specification; }

тогда при
Код

int cost =device.GetDeviceSpecification ().cost;

не будет копирования структуры.

Добавлено через 3 минуты и 43 секунды
А при
Код

device.GetDeviceSpecification ().cost = cost;

получишь ошибку компиляции вместо неожиданного поведения - присваивания полю временной структуры.
PM   Вверх
mes
Дата 14.10.2011, 19:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(PashaLost @  13.10.2011,  23:16 Найти цитируемый пост)
    static void SortByPower();                // сортировки
    static void SortByCost();
    static void SortByUseful();
    static void FindByPower(int, int);            // поиск
    static void FindByCost(int, int);
    static void FindByUseful(int, int);


ByCost, By.. и т.д.  можно вынести как предикат..вариантов масса, например так :
( с учетом того что это дом задание, как я понял, и опыта у вас пока не много)
Код

class DsComparer
{
   protected:
      typedef DeviceSpecification  ds;
   public:
     

     bool less (const ds& lhs, const ds& rhs) const
     { 
         return do_less(lhs, rhs);
     }
     bool greater  (const ds& lhs, const ds& rhs) const
     { 
         return do_less(rhs, lhs);
     }

     bool greater  (const ds& lhs, const ds& rhs) const
     { 
         return !do_less(lhs, rhs) && !do_less(rhs, lhs)
     }

    protected:
       virtual do_less  (const ds& lhs, const ds& rhs) const =0;

};

class ByCostDsComparer : DsComparer
{
    protected:
       virtual do_less  (const ds& lhs, const ds& rhs) const
       {
          return lhs.cost  < rhs.cost;
      }

};

теперь можете передавать сравнитель отдельным аргументом в алгоритм сортировки и поиска и задавать нужное поведение..

Добавлено @ 19:49
Цитата(math64 @  14.10.2011,  18:37 Найти цитируемый пост)
Лучше так:

не лучше, а так и должно оно было быть..спасибо что заметили опечатку smile


Это сообщение отредактировал(а) mes - 14.10.2011, 19:50


--------------------
PM MAIL WWW   Вверх
math64
Дата 14.10.2011, 19:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 12
Всего: 72



Вот можно ещё так извратиться:
Код

class Device {
public:
  class List {
    List(int n);
    ~List();
  private:
     Device* devices;
  }
private:
int cost;
};
typedef Device::List DeviceList;
Device::List::List(int n) {
  devices = new Device[n];
  for(int i=0; i<n; i++)
   devices[i].cost = i;
}
Device::List::~List() {
  delete[] devices;
}

PM   Вверх
mes
Дата 14.10.2011, 20:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(math64 @  14.10.2011,  18:54 Найти цитируемый пост)
Вот можно ещё так извратиться:


учитывая на каком вопросе споткнулся тс только этого ему для полного счастия не хватает  smile 


Добавлено через 46 секунд
я про nested class..


--------------------
PM MAIL WWW   Вверх
PashaLost
Дата 15.10.2011, 15:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 36
Регистрация: 18.1.2008

Репутация: нет
Всего: нет



всем отозвавшимся спасибо!!!
Хотел поставить плюсиков, но недостаточно ПРАВ !!! smile 
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0827 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.