Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Наследование и друзья - cannot access


Автор: bel_nikita 16.12.2005, 01:28
Конструкторы, деструкторы и др. пропускаю, да бы не отвлекать внимания.

Абстрактный класс cPCIDSPCard объявлен, как друг для абстрактного класса cPCIDSP (такое допустимо?)
Класс cPTMCD6 : public cPCIDSPCard вызывает метод ISR() класса cDSP6415 : public cPCIDSP
Код

class cPCIDSPCard;

class cPCIDSP
{
  friend class cPCIDSPCard;
protected:
  virtual int ISR() = 0;    //!< Interrupt routine.
};

class cDSP6415 : public cPCIDSP
{
//public:
  int ISR() { return 0; };
};

class cPCIDSPCard
{
public:
  virtual INT   ISR()         = 0;  //!< Interrupt routine.
  UINT GetMaxDSP() const { return m_uMaxDsp; }  //!< Get max DSP's on the board.
protected:
  class cPCIDSP**     m_pDSP;     //!< Pointer to the DSP's array.
  UINT                m_uMaxDsp;  //!< Max DSP's on the board.
};

class cPTMCD6 : public cPCIDSPCard
{
public:
  INT ISR()
  {
    for (UINT i = 0; i < GetMaxDSP(); ++i )
      m_pDSP[i]->ISR();  // <<< error C2248: 'ISR' : cannot access protected member declared in class 'cPCIDSP' <<<
    return 0;
  }
};

Метод cPCIDSP::virtual int ISR() = 0; делать public'ом нельзя.
Сделать другом cPTMCD6 не очень smile Потом появяться другие классы производные от cPCIDSPCard и придется и их делать друзьями для cPCIDSP.

Автор: chipset 16.12.2005, 01:33
Цитата(bel_nikita @ 15.12.2005, 15:28)
Сделать другом cPTMCD6 не очень  Потом появяться другие классы производные от cPCIDSPCard и придется и их делать друзьями для cPCIDSP.

Ну вроде как в этом и суть -- кому нужно, тех и сделаешь друзьями.

Автор: bel_nikita 16.12.2005, 01:44
Я в тупик попал с этим проектированием smile Все работает, но, блин, не красиво.
Есть некая PCI плата. На этой плате есть несколько DSP. Я разбиваю на классы: создаю абстракцию для DSP и абстракцию платы. Потом конкретизирую для типа DSP и платы.
По приходу интерапта, драйвер берет метод ПЛАТА::ISR() платы. В свою очередь этот ПЛАТА::ISR() должен вызвать ISR() каждого DSP на плате.

Автор: Mayk 16.12.2005, 12:19
Цитата(bel_nikita @ 16.12.2005, 05:28)
1) class cPCIDSPCard;

Вообще-то эта строка не нужна для объявления дружбы.

А так - сделай сделай в базовом DSP классе виртуальным метод ISR и объяви там же дружбу базовой схеме.

Что-то типа того

Код

class BaseDSP
{
     friend class BaseScheme;          
     virtual int ISR()=0;
};


class BaseScheme
{
     virtual int doISR_start(){return 0;};  //вызов ISR платы ДО обработки ISR DSP'ами
     virtual int doISR_finish(){return 0;}; //вызов ISR платы ПОСЛЕ обработки ISR DSP'ами

     protected:
     void ISR(){ //не знаю что такое ISR и DSP, но предполагаю, что
          doISR_start();  //плата может захотеть поработать как до DSP'ов
          for_each(m_dsp.begin(), m_dsp.end(), mem_fun(&BaseDSP::ISR)); 
          doISR_finish(); //так и после
     }
     vector<BaseDSP*> m_dsp;
};


class ActualDSP : public BaseDSP
{
      int ISR(){
          //something useful.  
      }
  
};

class  ActualPCICard : BaseScheme
{
    int doISR_start(){
       cout << "let's get party started!"";
    }
   int doISR_finish(){
       cout << "finish";
   }
   public:
   using BaseScheme::ISR;
};

int main()
{
   ActualPCICard p; p.ISR();
}


Автор: bel_nikita 16.12.2005, 13:21
Цитата(Mayk @ 16.12.2005, 11:19)
А так - сделай сделай в базовом DSP классе виртуальным метод ISR и объяви там же дружбу базовой схеме.

Так я же так и сделал, но у меня не идет smile

З.Ы.: MSVC6

Автор: Mayk 16.12.2005, 13:35
Цитата(bel_nikita @ 16.12.2005, 17:21)

Так я же так и сделал, но у меня не идет


Нет. Ты вызываешь ф-цию из наследуемого класса, а не из базового. А дружба в с++ не наследуется.

Код

class b{
        friend class base;
        int a();
};

struct base
{
        base(){
                b* bb = 0; 
                bb->a(); //можно
        }
};


struct derived : public base
{
        derived(){
                b* bb = 0;
                bb->a();//нельзя
        }
};

Автор: Earnest 16.12.2005, 18:25
Правильно Mayk советует.
Дружбу надо локализовать в базовых классах.
Только чтобы было погибче, сделай в своем cPCIDSPCard защищенный хелпер (только для наследников):

Код

class cPCIDSPCard
{
   ...
protected:
    int CallISR(cPCIDSP& p) { return p.ISR(); } 
}

Тогда потомки cPCIDSPCard смогут реализовывать любые схемы опроса потомков cPCIDSP

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)