понедельник, августа 15, 2005

Приватные чисто виртуальные функции

С первого взгляда такой код может вызвать некоторое удивление:
class CBase
{
private:
virtual void func()=0;
};
Как же так, приватная и чисто виртуальная функция? Ее же нельзя будет переопределить и вызвать из класса-наследника! Еще как можно. Уровень доступа и виртуальность друг от друга не зависят. То есть ее не только можно будет переопределить, ей можно будет сменить уровень доступа, сделать публичной, например...
class CDerived : public CBase
{
public:
virtual void func()
{
...
}
};
В каких ситуациях это может понадобится? Почему не сделать уровень доступа protected? Ну например, вы хотите, чтобы функция была переопределена в наследнике, но чтобы нельзя было вызвать функцию базового класса. Допустим, каждому классу нужен уникальный идентификатор. Тогда логичной выглядит такая иерархия.
class CBase
{
private:
virtual int getID()=0;
...
};

class CDerived : public CBase
{
private:
virtual int getID()
{
//возвращает ID
}
...
};

class CDerived1 : public CDerived
{
prvate:
virtual int getID()
{
//возвращает ID
}
...
};
Если попытаться описать функцию из CDerived1 как
int CDerived1::getID()
{
return CDerived::getID();
}
то компилятор скажет что-нибудь вроде "cannot access private member declared in class 'CDerived' ".

Technorati tag:

2 комментария:

  1. Странно - а у меня на g++ такое не пркатило

    #include

    using namespace std;

    class A
    {
    private:
    virtual void f() = 0;
    };

    class B: public A
    {
    private:
    void f()
    {
    cout << "Class B" << endl;
    }

    };

    int main(int argc, char** argv) {
    A *a = new B;
    a->f();
    return 0;
    }

    Compiler error:
    main.cpp:22: error: ‘virtual void A::f()’ is private

    а паачему?

    ОтветитьУдалить
  2. Max

    main.cpp:22: error: ‘virtual void A::f()’ is private

    а паачему?


    Функция приватна как в А, так и в В. Вызвать из main ее не получится. Можно сделать ее в В публичной, объявить указатель на В и тогда вызвать.

    ОтветитьУдалить