2009-03-10 6 views
0

Il s'agit d'un point impair. Notez que ceci est réduit le code d'exemple, et manque délibérément des destructeurs). J'utilise la classe Ptr de cet exemple dans un vecteur, comme un pointeur vers une classe dérivée.pointeur constant en tant qu'argument de constructeur

Comme nous pouvons le voir, le Ptr prend un Base<>* comme argument de constructeur.

Malheureusement, je besoin d'un constructeur qui prend une base de const <> *, et je ne peux pas simplement faire ceci:

Ptr(const Base<>* a) { in = const_cast<Base<>*>(a)}; 

Toute idée comment je peux faire accepter cette classe un const Base<>* comme il est constructeur?


Edit:

Ok, s'avère que je peux résoudre ce problème en modifiant le code indépendant, donc il est un peu un non-problème maintenant =] m'a pris environ un jour pour le fixer si = [

+1

Vous m'a perdu à "n'obtenez pas la supériorité ou quoi que ce soit". –

+0

Mes excuses. La dernière fois que j'ai posté un code d'exemple, un gars m'a raconté que je n'avais pas de destructeurs virtuels. –

Répondre

2

Je pense que vous devez définir une classe distincte pour renvoyer les pointeurs vers const, car non seulement les arguments du constructeur, mais aussi les types de retour des opérateurs doivent être remplacés par des versions const. Si vous faites le ConstPtr un friend de Ptr, cela devrait fonctionner assez bien:

template<...> 
class ConstPtr { 
    const Base<...> *in; 
    ConstPtr(Base<...>* a) { in = a; } 
    ConstPtr(const Base<...>* a) { in = a; } 
    ConstPtr(const Ptr<...> &a) { in = a.in; } 
    ... 
}; 

Pour construire des enveloppes de pointeurs premières, vous pouvez ajouter une fonction surchargée, plus ou moins comme ceci:

template<..., class P> 
P make_ptr(Base<...> *t); 

template<...> 
Ptr<...> make_ptr< ..., Ptr<...> >(Base<...> *t) { 
    return Ptr(t); 
} 

template<...> 
ConstPtr<...> make_ptr< ..., ConstPtr<...> >(const Base<...> *t) { 
    return ConstPtr(t) 
} 
+0

Une chance d'être un peu plus verbeux sur la syntaxe de l'ami? Ça ne marche pas comme je m'y attendais et j'aimerais voir ce que vous aviez en tête! –

+0

Mon plan était de mettre "ami ConstPtr <...>;" dans la définition de "Ptr <...>", pour laisser le constructeur de ConstPtr accéder "a.in". Je ne l'ai pas testé cependant et peut-être qu'il y a quelques complications dues aux gabarits. – sth

+0

Ok, c'est ce que j'ai fait. Y at-il un moyen de le jeter dans un ConstPtr automatiquement? Ce n'est pas une option pour avoir des classes distinctes pour les deux opti –

1

Votre classe Ptr a un membre de pointeur non const. Vous ne serez pas en mesure d'attribuer un const Base* sans certains lancers dangereux. Veux-tu çà? Essayez ceci:

template <class f, class g> 
class Ptr 
{ 
    public: 
    Ptr(){}; 
    Ptr(Base<f,g,Ptr<f,g> > const* a) { in = *a; } 
    Base<f,g,Ptr<f,g> >* operator->() 
    { 
     return &in; 
    }; 

    Base<f,g,Ptr<f,g> >& operator*() 
    { 
     return in; 
    }; 

private: 
    Base<f,g,Ptr<f,g> > in; 
}; 
+0

Hmm. Ça a l'air bien, mais si Base > a un membre de type Ptr , cela créera une classe de taille infinie. Mais je n'ai pas compris ce que l'OP essaie de faire, donc je ne suis pas sûr que ce soit le cas ... –

+0

Désolé, ce n'est pas une option faisable: je dois garder un pointeur sur l'objet original dans ce cas pas l'objet lui-même afin de faire des choses avec les adresses plus tard (ce n'est pas un code sympa). La version complète est un simulateur de réseau de neurones, donc il faudrait environ une semaine pour expliquer toute la situation! –

1

selon votre exemple, vous devriez faire

Ptr(const Base< f,g, Ptr< f, g > >* a) 
{ 
    in = const_cast< Base<f,g,Ptr<f,g> >* > (a); 
} 

ps: Je n'aime pas const_cast et dans des cas similaires, j'essaie d'éviter cela. Peut-être besoin de faire deux implémentation de Ptr pour les arguments const et non const.

+0

"Utilisation invalide de const_cast avec le type 'Ptr ', qui n'est pas un pointeur, une référence, ni un type de pointeur vers un membre de données." J'ai déjà dit que ce n'était pas une option. –

+0

Je ne sais pas pourquoi vous ne pouvez pas compiler mon échantillon. J'ai testé cela sur mon compilateur msvc 2005 - tout va bien. Veuillez fournir les informations les plus détaillées sur votre problème. – bayda

+0

Je comprends que le code DEVRAIT compiler. Cependant, pour des raisons complètement inconnues et probablement incroyablement complexes, ce n'est pas le cas, comme je l'ai dit dans la question. Je vais supprimer le -1 mais vous devriez vraiment lire la question avant de répondre. –

Questions connexes