2010-11-09 7 views
0

Laissez-moi vous donner un exemple simple:définitions de copie/constructeur de conversion (const/non-const)

class A 
{ 
public: 
    A() { cout << "A::A()" << endl; } 
    A(A const& a) : _a(a._a) { cout << "A::(A Copy Const)" << endl; } 
    A(A& a) : _a(a._a) { cout << "A::(A Copy)" << endl; } 

    template <typename _T1> 
    A(_T1& v1) : _a(v1) { cout << "A::(T conversion)" << endl; } 

    ~A() { cout << "A::~A()" << endl; } 

    void say() { cout << "A::say()" << endl; } 

private: 
    int _a; 
}; 

int main(int argc, char* argv[]) 
{ 
    A a1(A(argc)); // Line 1: ERM? 

    a1.say(); 

    return 0; 
} 

Couple de choses:

Y at-il de mal à la définition d'un const et non-const version du constructeur de copie? Raison pour laquelle je l'ai fait est que cela aide apparemment le compilateur différencier du constructeur basé sur un modèle, à savoir

A const a1(argc); 
A a2(a1); // <-- correctly call the const copy ctor 

A a3(argc); 
A a4(a3); // <-- correctly call the non-const copy ctor 

Y at-il une meilleure façon de faire en sorte que dans l'exemple ci-dessus, le constructeur de copie est toujours appelée sur le constructeur basé sur un modèle ? Deuxièmement, d'un point de vue du codage pur, la ligne 1 semble être correcte, l'intention est de créer un A temporaire avec argc, puis de déclencher le constructeur de copie, mais je reçois l'exception suivante (gcc 4.4.4):

erreur: demande de membre « dire » dans « a1 », qui est de type non-classe « A (A) »

Je crois que ce qui se passe ici est que le compilateur pense que a1 est une définition de fonction, est-ce correct? Si oui, quelle est la bonne façon d'écrire cette ligne de code particulière? Ce qui suit semble être un hack!

A a1(true ? A(argc) : A()); 

p.s. S'il vous plaît ignorer tous les foobars stylistiques et pourquoi exactement je veux faire ça ...! :)

Répondre

2

Un constructeur basé sur un modèle n'est jamais un constructeur de copie (formel).

Vous avez raison de dire qu'une déclaration qui pourrait être une déclaration de fonction est traitée comme une déclaration de fonction. C'est ce qu'on appelle "l'analyse la plus vexante" de C++. Une solution de contournement consiste à utiliser parenthèses supplémentaires, comme T v((U)).

Il se peut que l'ajout d'un mot-clé auto le corrigerait aussi, je n'ai pas essayé. Mais puisque auto acquiert une nouvelle signification en C++ 0x, ce n'est probablement pas une bonne idée de prendre l'habitude de l'utiliser même si cela fonctionne pour ce problème en C++ 98.

Salutations & hth.

+0

Auto ne semble pas fonctionner en C++ 98, mais la parenthèse a fait l'affaire! THX. – Nim

Questions connexes