Question

Comment mettre en œuvre la coulée à une classe de base privée en C ++? Je ne veux pas utiliser hacks comme l'ajout d'un ami, etc. Définition de l'opérateur de coulée publique ne fonctionne pas.

EDIT:

Par exemple, j'ai:

class A {
//base class
}

class AX : private A {
//a child
}

class AY : private A {
//another specialized child
}

class B {
//base class
void do (A a) {//do
    }
}

class BX : private B {
//a child
void do (AX a) {
     B::do( static_cast <A> (a) );
    }
}

class BY : private B {
//another specialized child
void do (AY a) {
    B::do( static_cast <A> (a) );
    }
}

EDIT2

Pourquoi dois-je faire cela?

Supposons que je dois définir une propriété qui est assez lourd et peut être de plusieurs types similaires (comme VelocityX VelocityY etc). Ensuite, je veux être en mesure d'avoir des classes qui peuvent avoir un ensemble de ces propriétés. Si je veux traiter ces propriétés, il est évident que je préfère les jetai à leur type de base que d'ajouter une mise en œuvre pour chaque variation. Je ne l'utilise l'héritage public, car il est préférable de jeter explicitement si nécessaire que d'avoir l'interface privée implicitement visible. Pas un vrai problème, mais je voudrais avoir une solution:)

Était-ce utile?

La solution

Si la définition d'un opérateur de coulée publique ne fonctionne pas, vous pouvez essayer avec une fonction régulière:

class D: private B {
    public:
        B& asB() { return static_cast<B&>(*this); }
};
...
D d;
d.asB().methodInB();
...

Quoi qu'il en soit, quel est le point? Si dérive de D privé de B, alors vous ne sont pas censés utiliser un D comme B de l'extérieur.

Autres conseils

Vous pouvez simplement utiliser un plâtre de style C. Pas besoin de « hacks » ou « mises en œuvre ». il enroulant dans une fonction explicite au service du peuple « C-moulages de style sont mauvais »

template<typename Targ, typename Src>
typename boost::enable_if<boost::is_base_of<Targ, Src>, Targ>::type &
private_cast(Src &src) { return (Targ&)src; }

Pour que le coffre-fort de la distribution, vous devez vous assurer que Targ est en fait une base privée ou publique. Cela se fait par boost::is_base_of.


Bien sûr, vous devriez préférer les fonctions membres dans la classe dérivée respective qui renvoient le pointeur de base, au lieu de faire un casting. .


  

Définition de l'opérateur de coulée publique ne fonctionne pas.

Cela ne me fait pas de sens ... Pourquoi faire la classe de base privée du tout alors? Il suffit de le rendre public. La raison pour laquelle vos fonctions de conversion ne fonctionnent pas parce que la norme exige que les conversions implicites ne considèrent jamais les fonctions de conversion à une classe de base, la classe elle-même ou void.

J'ai un cas d'utilisation pour cela; Je suis héritant d'une classe de base importante et volatile qui ajoute des fonctions tout le temps et presque jamais est la fonction de la classe de base va fonctionner correctement dans ma sous-classe, donc je hériterai privé.

Je pense qu'il est plus simple que de faire une fonction qui retourne la classe de base. Ci-dessous je liste un programme entièrement corrigé; s'il vous plaît essayer de compiler votre code avant de soumettre une question, puisque l'utilisation des identifiants comme « faire » que les noms de fonction est susceptible de rendre chaque compilateur malheureux .. :-(: - (

class A {
  //base class                                                                                                                                                          
};

class AX : private A {
  //a child                                                                                                                                                             
 public:
  A *ToA() { return this; }
};

class AY : private A {
  //another specialized child                                                                                                                                           
 public:
  A *ToA() { return this; }
};

class B {
  //base class                                                                                                                                                          
 protected:
  void do_it (A a) {};
};

class BX : private B {
  //a child                                                                                                                                                             
  void do_it (AX a) {
    B::do_it( *a.ToA() );
  }
};

class BY : private B {
  //another specialized child                                                                                                                                           
  void do_it (AX a) {
    B::do_it( *a.ToA() );
  }
};

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top