Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[Qt,KDE] D-pointer, wielokrotne dziedziczenie

Ostatnio zmodyfikowano 2014-04-24 17:41
Autor Wiadomość
b00rt00s
Temat założony przez niniejszego użytkownika
[Qt,KDE] D-pointer, wielokrotne dziedziczenie
» 2014-04-24 14:55:09
Szukałem informacji na temat jak wykonać implementację prywatną w hierarchii klas. Znalazłem taki opis w dokumentacji KDE.
Czegoś jednak nie rozumiem. Weźmy przykład z cytowanej strony (implementację pomijam):
C/C++
class KFooBasePrivate;
class KFooBase
    : public QObject
{
public:
    KFooBase( QObject * parent );
    ~KFooBase();
    void setSomeInteger( int i );
    int someInteger() const;
protected:
    const QScopedPointer < KFooBasePrivate > d_ptr;
    KFooBase( KFooBasePrivate & dd, QObject * parent );
private:
    Q_DECLARE_PRIVATE( KFooBase )
};

class KFooDerivedPrivate;
class KFooDerived
    : public KFooBase
{
public:
    KFooDerived( QObject * parent );
    void setAnotherInteger( int i );
    int anotherInteger() const;
    int sumOfIntegers() const;
protected:
    KFooDerived( KFooDerivedPrivate & dd, QObject * parent ); //ten konstruktor pozwala na dalsze dziedziczenie i zmianę implementacji prywatnej
private:
    Q_DECLARE_PRIVATE( KFooDerived )
};

Załóżmy, że powyższy kod jest jest skompilowany do biblioteki dzielonej (nazwijmy ją BIB.so). Teraz napiszę klasy dziedziczące po KFooDerived i KFooDerivedPrivate. Niech to będzie częścią programu PROG, do którego dołączona jest biblioteka BIB.so.
C/C++
class KFooDerivedAgainPrivate;
class KFooDerivedAgain
    : public KFooDerived
{
    //reszta deklaracji
};

class KFooDerivedAgainPrivate
    : public KFooDerivedPrivate
{
    //reszta deklaracji
};

I tu mam problem. Jeśli zmienię klasę KFooDerivedPrivate tak, aby była niekompatybilna z poprzednią wersją, to PROG nie będzie mógł wykorzystać nowej wersji, ze względu na to, że KFooDerivedAgainPrivate dziedziczy po starej wersji klasy KFooDerivedPrivate.

I jaki ma to sens? Przecież idiom implementacji prywatnej powinien pozwalać na dowolną modyfikację klasy prywatnej bez ryzyka utraty kompatybilności binarnej.

A może powinno być tak - zamiast:
KFooDerived( KFooDerivedPrivate & dd, QObject * parent );

powinno być:
KFooDerived( KFooBasePrivate & dd, QObject * parent );

oraz zamiast:
C/C++
class KFooDerivedAgainPrivate
    : public KFooDerivedPrivate
powinno być:
C/C++
class KFooDerivedAgainPrivate
    : public KFooBasePrivate

Wówczas zmiany w KFooDerivedPrivate nie będą miały znaczenia, dla klasy KFooDerivedAgainPrivate i kompatybilność binarna będzie zachowana.

Mam rację, czy coś mi umknęło?
P-108591
Monika90
» 2014-04-24 17:41:20
Teraz napiszę klasy dziedziczące po KFooDerived i KFooDerivedPrivate. Niech to będzie częścią programu PROG, do którego dołączona jest biblioteka BIB.so.
Czy chodzi ci o to, że klasa KFooDerivedAgainPrivate jest częścia twojego programu, który używa biblioteki? Takie coś nie jest możliwe, nie możesz dziedziczyć z klas KFooBasePrivate i KFooDerivedPrivate, bo nie masz ich definiji, ich definicje są ukryte wewnątrz biblioteki. Jedyne co masz to plik nagłówkowy z deklaracją zapowiadającą
class KFooDerivedPrivate;
 (i plik binarny), z punktu widzenia twojego programu, KFooDerivedPrivate jest typem niekompletnym - po takim typie nie można dziedziczyć.
P-108601
« 1 »
  Strona 1 z 1