innych odpowiedzi wyjaśnić uzasadnienie zapobiegania swój obiekt B
dostępu chronione części A
w twoim przykładzie, mimo że B
'to-a' A
. Oczywiście najłatwiejszym sposobem rozwiązania tego problemu jest udostępnienie części publicznych lub publicznie dostępnych metod dostępu.
Użytkownik może jednak uznać, że jest nieodpowiedni (lub może nie mieć kontroli nad definicją A
). Oto kilka sugestii, które pozwolą ci rozwiązać ten problem, zwiększając kolejność podważania kontroli dostępu A
. Zauważ, że wszystkie te obejścia zakładają, że class A
jest konstrukcją do kopiowania.
W pierwszym przypadku, po prostu użyć konstruktora kopia dla A
założyć stan początkowy dla tej części obiektu B
, a następnie naprawić go potem:
class B1 : public A
{
public:
B1() : A(), z(0) {}
B1(const A& item) : A(item), z(1) {
// fix up the A sub-object that was copy constructed
// not quite the way we wanted
x = y;
y = 0;
}
private:
int z;
};
Uważam, że niezwykle kłopotliwe i prawdopodobnie bardzo podatny na błędy (zakładając, że chcemy, aby obiekt podrzędny A
w obiekcie B
był inny niż obiekt A
przekazywany do konstruktora - nietypowa sytuacja, ale to, co podano w problemie).Jednak fakt, że można to zrobić, daje pewne uzasadnienie dla bardziej wywrotowych przykładów, które następują ...
Następny przykład tworzy tymczasowy obiekt B
, który ma dokładny duplikat obiektu A
, do którego chcemy uzyskać dostęp. Następnie można użyć tymczasowego B
obiektu dostać się do elementów, które były chronione:
class B2 : public A
{
public:
B2() : A(), z(0) {}
B2(const A& item) : A(), z(1) {
// create a special-use B2 object that can get to the
// parts of the A object we want access to
B2 tmp(item, internal_use_only);
x = tmp.y; // OK since tmp is of type B
}
private:
int z;
// create a type that only B2 can use as a
// 'marker' to call a special constructor
// whose only purpose in life is to create
// a B object with an exact copy of another
// A sub-object in it
enum internal_use {
internal_use_only
};
B2(const A& item, internal_use marker) : A(item), z(0) {};
};
uważam, że rozwiązanie się być nieco mniej kłopotliwe niż pierwszy, ale to wciąż niejasna (moim zdaniem). Posiadanie bastardowej wersji obiektu B tylko po to, aby dostać się do części obiektu, który chcemy, jest dziwne.
Możemy coś z tym zrobić, tworząc specjalny serwer proxy dla obiektów A
, który zapewnia wymagany dostęp. Zauważ, że jest to "najbardziej wywrotowe obejście", ponieważ jest to coś, co każda klasa może zrobić, aby dostać się do chronionych części A
, nawet jeśli same nie są podklasami A
. W przypadku klasy B
istnieje pewna legitymacja, aby uzyskać dostęp do chronionych części obiektów A
, ponieważ B
to-A
, a jak już widzieliśmy, istnieją obejścia, które pozwalają nam uzyskać dostęp, które już wykorzystują prawa, które już są class B
ma, więc uważam to za czystszą wersję tych obejść w przypadku class B
.
Być może zapomniałeś 'wirtualny'? –
Pavel: oops, tak, dodałem słowo kluczowe 'virtual' ... tak naprawdę nie zmienia to mojego punktu, chociaż :) –