2009-03-11 9 views
4

Est-ce que l'ajout d'une nouvelle fonction membre dans la définition de classe de pointeur d efface la compatibilité binaire?Est-ce que l'ajout d'une nouvelle fonction membre dans la classe d pointer rompt la compatibilité binaire?

Par exemple, la nouvelle définition ci-dessous va-t-elle rompre la compatibilité binaire par rapport à l'original? (Question de côté, est-il un outil qui me dire si une nouvelle compatibilité binaire casse .donc par rapport à l'ancien .donc Sinon, comment puis-je vérifier manuellement?)

Original:

#ifndef __TESTBC_H__ 
#define __TESTBC_H__ 
class APrivate; 

class A 
{ 
    public: 
    int get() { d->update(); return _d->get(); } 

private: 
    APrivate *_d; 

}; 

class APrivate 
{ 
    public: 
    int get() { return _val; } 
    void update() { _val = 1; } 

    private: 
    int _val; 
}; 
#endif 

New:

#ifndef __TESTBC_H__ 
#define __TESTBC_H__ 
class APrivate; 

class A 
{ 
    public: 
    int get() { _d->update(); return _d->get(); } 

private: 
    APrivate *_d; 

}; 

class APrivate 
{ 
    public: 
    int get() { return _val; } 
    void update() { _val = 1; multiply(); } 
    void multiply() { _val = _val * 10; } 

    private: 
    int _val; 
}; 
#endif 

FYI: Je comprends que la classe d pointer doit être spécifiée dans le fichier cc au lieu de l'en-tête. L'exemple ci-dessus est conçu pour se concentrer sur le problème de compatibilité binaire.

+0

La tuile peut être améliorée ... il clarifie mieux que cette nouvelle fonction est ajoutée à une classe privée. – IsaacS

Répondre

5

Non, ce n'est pas le cas.

Vous devez comprendre comment C++ construit ses objets.

Dans votre cas, il s'agit juste de la classe "POD" avec des fonctions membres non virtuelles. Ces fonctions n'affectent pas la représentation de l'objet en mémoire. Ainsi, la nouvelle version est compatible avec les anciennes versions binaires.

Plus que cela, si vous n'exposez pas votre classe "APrivate" à l'utilisateur. (Ne pas donner un en-tête juste en avant la déclaration), vous ne freineriez pas une API même si vous faites beaucoup plus de changements .

Signification:

#ifndef YOUR_PUBLIC_API 
#define YOUR_PUBLIC_API 
class bar; 
class foo { 
public: 
    // member functions using bar 
private: 
    bar *bar_; 
}; 
#endif 

Vous ne même pas exposer bar donc vous pouvez le modifier de quelque façon que vous le souhaitez. C'est la meilleure façon de rendre les bibliothèques C++ ABI compatibles.

+0

Je suppose ABI, pas API. > "vous ne freineriez pas une API" – IsaacS

1

Envisagez d'utiliser l'outil abi-compliance-checker, il vérifie les fichiers d'en-tête et les bibliothèques partagées et recherche les modifications ABI susceptibles de rompre la compatibilité binaire.

+0

abi-compliance-checker, alias, AbiCC –