Изменение уровня доступа в производном классе
От: igna Россия  
Дата: 29.05.06 09:18
Оценка:
C++ позволяет изменять уровень доступа к членам в производном классе в любую сторону, Java — только в сторону повышения уровня доступа, а C# — не позволяет вообще.

Понятно, что этим Java обеспечивает возможность рассматривать любой объект производного класса как объект базового класса, C++ — свободу программиста, а вот почему C# не позволяет изменять уровень доступа в сторону повышения, мне не ясно.

Кроме того было бы интересно узнать, как осмысленно можно применить понижение (в C++) и повышение (в C++ и Java) уровня доступа?
Re: Изменение уровня доступа в производном классе
От: Nikolay_Ch Россия  
Дата: 29.05.06 09:33
Оценка:
I> а C# — не позволяет вообще.
Почему? Вроде позволяет...
Re: Изменение уровня доступа в производном классе
От: Cyberax Марс  
Дата: 29.05.06 09:39
Оценка:
igna wrote:
> C++ позволяет изменять уровень доступа к членам в производном классе в
> любую сторону
Не совсем так. В С++ механизмы контроля доступа и виртуальных функций —
независимы.

Поэтому можно делать так:
class jam_rule
{
...
public:
    //Invoke rule.
    void invoke(jam_frame *frame, jam_list *res)
    {
        checkParams(frame); //Проверить параметры вызова
        do_invoke(frame,res);
    }

private:
    virtual void do_invoke(jam_frame *frame,jam_list *res)=0;
};

class native_rule : public jam_rule
{
...
private:
    virtual void do_invoke(jam_frame *frame,jam_list *res)
    {
        ...
    }
};

class saved_rule : public jam_rule
{
...
private:
    virtual void do_invoke(jam_frame *frame,jam_list *res)
    {
        ...
    }
};

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

Более подробно: http://www.ddj.com/dept/cpp/184403760
Posted via RSDN NNTP Server 2.0
Sapienti sat!
Re: Изменение уровня доступа в производном классе
От: bolshik Россия http://denis-zhdanov.blogspot.com/
Дата: 29.05.06 09:40
Оценка: 2 (1)
Здравствуйте, igna, Вы писали:

I>Кроме того было бы интересно узнать, как осмысленно можно применить понижение (в C++) и повышение (в C++ и Java) уровня доступа?


Джава:
java.lang.Object(), метод clone() имеет модификатор доступа protected ==> если мы хотим предоставить клиенту, работающему с объектом нашего класса(неявно унаследованного от Object), возможность получить копию нашего объекта с помощью интерфейса, предусматриваемого стандартной библиотекой(clone()), мы должны переопределить этот метод с повышением модификатора доступа. Т.е. если клент видит, что в нашем классе присутствует public clone(), он знает, что создатель класса позаботился о правильной реализации клонирования. Конечно, альтернативой всему этому выступает написание метода типа makeClone() и забивание на Object.clone(), но другого применения повышения модификатора доступа не знаю
http://denis-zhdanov.blogspot.com
Re[2]: Изменение уровня доступа в производном классе
От: igna Россия  
Дата: 29.05.06 10:09
Оценка:
Здравствуйте, Nikolay_Ch, Вы писали:

N_C>Почему? Вроде позволяет...


А тут (см. ниже) о чем?:

17.5.4 Override methods

. . .

• The override declaration and the overridden base method have the same declared accessibility. In other
words, an override declaration cannot change the accessibility of the virtual method.

. . .

(C# Language Specification, 3rd Edition / June 2005)

Re[2]: Изменение уровня доступа в производном классе
От: igna Россия  
Дата: 29.05.06 10:11
Оценка:
Здравствуйте, Cyberax, Вы писали:

C>Не совсем так. В С++ механизмы контроля доступа и виртуальных функций — независимы.


Я вот о чем:

class B {
    public:
        void f() {}
    protected:
        void g() {}
    private:
        void h() {}
};

class D1 : public B {
    public:
        void g() {}
    protected:
        void h() {}
    private:
        void f() {}
};

class D2 : public B {
    public:
        void h() {}
    protected:
        void f() {}
    private:
        void g() {}
};
Re[3]: Поправка
От: igna Россия  
Дата: 29.05.06 10:21
Оценка:
Забыл virtual:

class B {
    public:
        void virtual f() {}
    protected:
        void virtual g() {}
    private:
        void virtual h() {}
};

class D1 : public B {
    public:
        void virtual g() {}
    protected:
        void virtual h() {}
    private:
        void virtual f() {}
};

class D2 : public B {
    public:
        void virtual h() {}
    protected:
        void virtual f() {}
    private:
        void virtual g() {}
};
Re: Ошибочно помечено для удаления
От: igna Россия  
Дата: 29.05.06 10:25
Оценка:
Re[3]: Изменение уровня доступа в производном классе
От: Nikolay_Ch Россия  
Дата: 29.05.06 10:32
Оценка:
N_C>>Почему? Вроде позволяет...
I>А тут (см. ниже) о чем?:
I>

I>• The override declaration and the overridden base method have the same declared accessibility. In other
I>words, an override declaration cannot change the accessibility of the virtual method.

Так это идет речь о виртуальных методах. А в обычных — пожалуйста — переопределяй, как хочешь.
public class Class1
{
    protected void qqq()
    {
    }
}

public class Class2 : Class1
{
    public new void qqq()
    {
    }
}
Re[4]: Изменение уровня доступа в производном классе
От: igna Россия  
Дата: 29.05.06 11:02
Оценка:
Здравствуйте, Nikolay_Ch, Вы писали:

N_C>Так это идет речь о виртуальных методах. А в обычных — пожалуйста — переопределяй, как хочешь.


При помощи new можно и виртуальный "переопределить":

public class Class1
{
    protected virtual void qqq()
    {
    }
}

public class Class2 : Class1
{
    public virtual new void qqq()
    {
    }
}
Re[5]: Изменение уровня доступа в производном классе
От: Nikolay_Ch Россия  
Дата: 29.05.06 11:07
Оценка:
I>При помощи new можно и виртуальный "переопределить":
Но по сути это же будет переопределение. Чем грозит переопределение через new в невиртуальных функциях?
Re[6]: Изменение уровня доступа в производном классе
От: igna Россия  
Дата: 29.05.06 11:17
Оценка:
Здравствуйте, Nikolay_Ch, Вы писали:

N_C>Но по сути это же будет переопределение.


Сокрытие.
Re[7]: Изменение уровня доступа в производном классе
От: Nikolay_Ch Россия  
Дата: 29.05.06 11:24
Оценка:
N_C>>Но по сути это же будет переопределение.
I>Сокрытие.
С такой точки зрения, тогда C# вообще не позволяет переопределять методы, за исключением виртуальных.
Хотя MSDN говорит:

Hiding an inherited member means that the derived version of the member replaces the base-class version.

Значит все-таки метод заменяет базовый метод...
Re[3]: Изменение уровня доступа в производном классе
От: Cyberax Марс  
Дата: 29.05.06 11:39
Оценка:
igna wrote:
> C>Не совсем так. В С++ механизмы контроля доступа и виртуальных функций
> — независимы.
> Я вот о чем
Ну так я именно это и имею в виду. В С++ биндинг виртуальных функций
идет по имени (и не включает в себя контроль доступа).
Posted via RSDN NNTP Server 2.0
Sapienti sat!
Re[4]: Изменение уровня доступа в производном классе
От: igna Россия  
Дата: 29.05.06 11:53
Оценка:
А почему "C++ позволяет изменять уровень доступа к членам в производном классе в любую сторону" это "не совсем так"?
Re[8]: Изменение уровня доступа в производном классе
От: igna Россия  
Дата: 29.05.06 11:56
Оценка:
Здравствуйте, Nikolay_Ch, Вы писали:

N_C>С такой точки зрения, тогда C# вообще не позволяет переопределять методы, за исключением виртуальных.


Конечно.

N_C>Хотя MSDN говорит:

Hiding an inherited member means that the derived version of the member replaces the base-class version.

N_C>Значит все-таки метод заменяет базовый метод...

"Заменяет" не значит "переопределяет".
Re[5]: Изменение уровня доступа в производном классе
От: Cyberax Марс  
Дата: 29.05.06 12:09
Оценка:
igna wrote:
> А почему "C++ позволяет изменять уровень доступа к членам в производном
> классе в любую сторону" это "не совсем так"?
Он не меняет доступ — он просто на него не смотрит
Posted via RSDN NNTP Server 2.0
Sapienti sat!
Re[6]: Изменение уровня доступа в производном классе
От: igna Россия  
Дата: 29.05.06 12:38
Оценка:
Здравствуйте, Cyberax, Вы писали:

>> А почему "C++ позволяет изменять уровень доступа к членам в производном классе в любую сторону" это "не совсем так"?


C>Он не меняет доступ — он просто на него не смотрит


И фраза вроде "The access of a member of a base class can be changed in the derived class" не имеет смысла?
Re[4]: Поправка
От: ekamaloff Великобритания  
Дата: 31.05.06 05:22
Оценка:
Здравствуйте, igna, Вы писали:

<...>

Я думал ты об этом:

class A {
public:
    void f() {}
};

class B: public A {
private:
    using A::f;
};

int main()
{
    B b;
    b.f();       // Ошибка, доступ к приватному члену
    ((A&)b).f(); // ОК, отсюда смонительная польза возможности понижения уровня доступа к производных классах, 
                 // раз это все равно можно обойти при желании
}


Кстати к Java еще можно добавить Delphi, он тоже позволяет только повышать уровень доступа.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
It is always bad to give advices, but you will be never forgiven for a good one.
Oscar Wilde
Re[2]: Изменение уровня доступа в производном классе
От: ekamaloff Великобритания  
Дата: 31.05.06 05:31
Оценка:
Здравствуйте, bolshik, Вы писали:

B>Джава:

B>java.lang.Object(), метод clone() имеет модификатор доступа protected ==> если мы хотим предоставить клиенту, работающему с объектом нашего класса(неявно унаследованного от Object), возможность получить копию нашего объекта с помощью интерфейса, предусматриваемого стандартной библиотекой(clone()), мы должны переопределить этот метод с повышением модификатора доступа. Т.е. если клент видит, что в нашем классе присутствует public clone(), он знает, что создатель класса позаботился о правильной реализации клонирования. Конечно, альтернативой всему этому выступает написание метода типа makeClone() и забивание на Object.clone(), но другого применения повышения модификатора доступа не знаю

С Java плохо знаком, но вроде у метода clone есть и еще одна особенность — он кидает исключение CloneNotSupportedException, если поддержка клонирования актуальным классом объекта не поддерживается. Зачем спрашивается такая двойная защита — через уровень доступа и исключения?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
It is always bad to give advices, but you will be never forgiven for a good one.
Oscar Wilde
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.