2010-11-14 2 views
1

Suivre l'exemple suivant:Comment puis-je initialiser les paramètres de super-classe à partir du C-Tor enfant en C++?

class A { 
public: 
    A(int param1, int param2, int param3) { 
     // ... 
    } 
}; 

class B : public A { 
public: 
    B() : m_param1(1), m_param(2), m_param(3), A(m_param1, m_param2, m_param3) { 
     // ... 
    } 
}; 

B b; 

Il est évident que, lorsque « b » sera créé, le cteur de A sera appelé avant que les paramètres de B seront réinitialisés. Cette règle m'empêche de créer des classes «wrapper» qui simplifient l'initialisation de la classe.

Quelle est la «bonne façon» de le faire?

Merci, Amir

PS: Dans mon cas particulier, les paramètres ne sont pas primitives, cet exemple que m'a aidé à me expliquer.

+0

Je comprends le problème. Cependant, cela ressemble à la duplication d'informations. Pourquoi seriez-vous dans une situation où vous devez initialiser à la fois «A» et «B» avec les mêmes paramètres? –

+0

Plus précisément, j'utilise la bibliothèque de physique "Bullet", qui prend des pointeurs sur des objets en tant que paramètres. Je veux créer et stocker un objet dans la classe enfant et passer son pointeur à la superclasse. Par ce que je peux créer une classe de caractère qui hérite de la classe de "l'objet physique" de la bibliothèque. – Amir

+0

Je ne suis pas sûr que je reçois la question, mais rappelez-vous une chose - les instructions de la liste d'initialisation ne s'exécutent pas dans l'ordre indiqué, elles sont exécutées dans les classes de base de commande et les variables membres dans la déclaration de classe. –

Répondre

2

« Les paramètres ne sont pas primitives ». Donc tu as quelque chose comme ça?

class Param { /*...*/ }; 
class A { 
public: 
    A(const Param& param1, const Param& param2, const Param& param3); 
}; 

class B : public A { 
public: 
    B(); 
private: 
    Param m_param1; 
    Param m_param2; 
    Param m_param3; 
}; 

Et vous voulez passer les membres de B au constructeur de A. Que dis-tu de ça?

class B_params { 
protected: 
    B_params(int v1, int v2, int v3); 
    Param m_param1; 
    Param m_param2; 
    Param m_param3; 
}; 
class B : private B_params, public A { 
public: 
    B(); 
}; 

B_params::B_params(int v1, int v2, int v3) 
    : m_param1(v1), m_param2(v2), m_param3(v3) {} 
B::B() : B_params(1,2,3), A(m_param1, m_param2, m_param3) {} 

Assurez-vous B_params vient avant A dans la liste des B « s classes héritées.

+0

Je connaissais déjà cette méthode, mais je préfère ne pas utiliser l'héritage multiple. Je vais probablement utiliser cette méthode, parce que je peux voir n'importe quelle autre solution à part cela et le modèle de conception "Factory". Je vais juste attendre un peu plus longtemps pour voir si une meilleure solution viendra. – Amir

4

Il suffit d'appeler le constructeur A:

class B : public A 
{ 
public: 
    B() : A(1 ,2, 3) 
    { 
    }; // eo ctor 
}; // eo class B 

EDIT:

lire votre commentaire à votre message original. Il est important d'être clair sur ces choses :) Quoi qu'il en soit, cette réponse est toujours vrai si vous voulez créer de nouvelles données en B, suivre en B, et passer à A:

class Object 
{ 
private: 
    int i; 
public: 
    Object(int _i) : i(_i){}; 
}; 

class A 
{ 
public: 
    A(Object* _1, Object* _2, Object* _3) 
    { 
    }; 
}; 

class B : public A 
{ 
private: 
    Object* _1; 
    Object* _2; 
    Object* _3; 

public: 
    B() : A(_1 = new Object(1), _2 = new Object(2), _3 = new Object(3)) 
    { 
    }; 
}; 
+0

êtes-vous sûr que 'B :: _ 1' etc. ne sera pas annulé après que' A (Object *, ...) 'est appelé? –

+0

Il n'y a aucune raison de le faire, l'objet (à ce stade) a été alloué. J'ai testé le VS2010 ci-dessus, donc je ne peux pas commenter sur d'autres compilateurs. Je ne vois pas pourquoi ce serait un problème. –

+0

pense à 'B(): _ 1 (nouvel objet (1)), _ 2 (nouvel objet (2)), _ 3 (nouvel objet (3)), A (_1, _2, _3) {}'. cela va gâcher en raison de l'ordre d'exécution réel. en fait, important, cela fonctionne simplement:] –

0

Pas sûr que je Je reçois votre question.

Si vous voulez juste quelque chose qui vous aide à initialiser A avec certains paramètres donnés, vous devez utiliser un Un constructeur avec des valeurs par défaut:

class A { 
public: 
    A(int param1 = 1, int param2 = 2, int param3 =3) { 
     // ... 
    } 
}; 
+0

Non, A est une classe donnée que je dois simplifier. – Amir

Questions connexes