нюансы организации friend-методов
От: _hum_ Беларусь  
Дата: 02.06.15 15:23
Оценка:
Раньше думал, что френд-функция ничем по семантике использованию не отличается от френд-классов, а оказалось, для нее не проходят вещи, которые вроде бы должны были проходить. А именно, не компилируется код, наподобие следующего:
class CA;

////////////////////////////////
////          CI            ////
////////////////////////////////
class CI
{
    int m_i;

    friend void CA::LaunchProcess(void);
public:
    //----------------------
    int get_value(void)const
    {
        return m_i;
    }
    //----------------------
};
////////////////////////////////

////////////////////////////////
////          CA            ////
////////////////////////////////
class CA
{
    CI  m_ProcessResult;

    int m_j;
    //----------------------
    void LaunchProcess(void)
    {
        m_ProcessResult.m_i = 0;// Ошибка: error C2248 : невозможно обратиться к private член
    }
    //----------------------
    void ReactOnProcessResult(void)
    {
        if(m_ProcessResult.get_value() == 1)
        {
            //<initiate nuclear strike>
        };
    }
    //----------------------
    void Foo_1(void)
    {
        //---
        if(m_ProcessResult.get_value() == 1)
        {
            ++m_j;
        };
        //---
    }
    //----------------------
    void Foo_2(void);
    void Foo_3(void);
    //<....>

};
////////////////////////////////


На всякий случай, зачем мне это нужно. Пишу на микроконтроллере, потому приходится постоянно идти на компромисс между прозрачностью кода и быстродействием/объемом памяти. С другой стороны пишу систему, ошибки в работе которой могут дорого стоить. В связи с этим хочу хоть как-то себя обезопасить. В частности, стоит проблема в том, чтобы гарантировать, что данную переменную объекта может менять только заданный метод, но никак не другой. Например, указанный выше код есть попытка решения этой проблемы для случая, когда наивный код выглядел бы так:

///////////////////////////////
////          CA            ////
////////////////////////////////
class CA
{
    int m_i;

    int m_j;
    //----------------------
    void LaunchProcess(void)
    {
        m_i = 0;
    }
    //----------------------
    void ReactOnProcessResult(void)
    {
        if(m_i == 1)
        {
            //<initiate nuclear strike>
        };
    }
    //----------------------
    int Foo_1(void)
    {
        //---
        if(m_i == 1)//например, можно ошибиться и написать m_i = 1
        {
            ++m_j; //например, можно ошибиться и написать ++m_i; 
        };
        //---
        m_i = Foo_2(); // например, можно понадеяться, что Foo_2 всегда дает нуль, а потом забыть, и в Foo_2 начать писать нетривиальный код
    }
    //----------------------
    int Foo_2(void)
    {
        return 0; 
    }
    //----------------------
    int Foo_3(void);
    //<....>

};
////////////////////////////////


Заранее благодарю за конструктивные предложения.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.