2010-10-16 13 views
3

Dans le fichier test.cpp, j'ai ceci:héritage C++ Question

template <typename T> 
class A 
{ 
public: 
    A(int a){}; 
    virtual ~A(); 

private: 
}; 

class B : public A<int> 
{ 
public: 
    B(int a):A(a){}; 
    virtual ~B(); 

private: 
}; 

int main() 
{ 
    return 0; 
} 

Quand je compile, je reçois ceci:

[email protected]:~/Documents/ECLibrary$ g++ -g -Wall -Wextra -pedantic-errors test.cpp -o tdriver 
test.cpp: In constructor ‘B::B(int)’: 
test.cpp:14: error: class ‘B’ does not have any field named ‘A’ 
test.cpp:14: error: no matching function for call to ‘A<int>::A()’ 
test.cpp:5: note: candidates are: A<T>::A(int) [with T = int] 
test.cpp:3: note:     A<int>::A(const A<int>&) 

Je ne veux pas un constructeur par défaut pour ma base classe, car cela n'a pas de sens dans mon code. Je veux juste que ma classe dérivée exécute le constructeur appelé de la classe de base et fasse une construction supplémentaire pour les choses supplémentaires dans la classe dérivée. Je ne sais vraiment pas pourquoi il essaie d'appeler le constructeur par défaut de la classe de base lorsque j'essaie d'appeler explicitement un autre constructeur. Est-ce que j'ai râté quelque chose?

Merci

+0

Avez-vous implémenté un constructeur de classe A? –

+1

Vous avez sûrement vu à quoi ressemblerait le post puisque vous deviez faire défiler l'aperçu pour le soumettre. Lisez la FAQ d'édition et utilisez la barre d'outils d'édition pour éditer vos messages, pas seulement deviner. (Evident par '[code]' et autres joyeusetés.) Vous êtes en train de jouer toutes les corrections que les autres font, en ignorant complètement l'aperçu à chaque fois. Je veux presque -1 juste pour ça. Vous n'approchez pas toutes les tâches de cette façon? – GManNickG

+2

Qu'est-ce que ce mot 'modèle' fait là? Quoi qu'il en soit, s'il vous plaît modifier comme suit: mettre le code sur des lignes séparées, sélectionnez ces lignes, et cliquez sur le bouton format-as-code (il a des zéros et des uns dessus). Cheers, –

Répondre

9

Vous pouvez ajouter la liste des arguments de modèle pour A:

B(int a) : A<int>(a) { } 

Notez que le code que vous avez - en utilisant A sans la liste des arguments de modèle - est valide C++. Comeau et Visual C++ 2010 acceptent le code tel quel.

g ++ 4.3 n'accepte pas le code sans la liste d'arguments modèle. Peut-être que quelqu'un peut tester une version ultérieure de g ++ ou vérifier la base de données de bogues g ++ pour voir s'il s'agit d'un problème connu (je n'utilise pas régulièrement g ++ et je ne connais pas leur base de données de bogues).

+0

Tout comme MSVC ... –

+0

@Oli: Bon à savoir. Peut-être que quelqu'un ici peut tester avec une version ultérieure de g ++ et/ou vérifier la base de données de bugs g ++. J'ai peur de ne pas utiliser g ++ assez régulièrement pour le connaître. –

+0

Merci, cela a fonctionné. Je suis tellement rouillé avec C++. –

3

Essayez plutôt B(int a):A<int>(a){}.

0

a besoin de lire:

class B : public A<int> 
{ 
public: 
    B(int a):A<int>(a){}; 
    virtual ~B(); 

private: 
}; 

et il fonctionnera très bien.

-1

Vous essayez d'initialiser votre classe de base comme A, mais vous ne tirez pas de A, vous dérivez de A<int>

+0

Le nom de classe injecté pour un modèle peut être utilisé avec ou sans la liste d'arguments du modèle, aussi longtemps que 'A' est sans ambiguïté, vous pouvez utiliser' A' et 'A ' de façon interchangeable (si vous avez dérivé de deux spécialisations de 'A', comme dans la classe B: A , A {};', alors 'A' serait ambigu à l'intérieur de' B' et vous devriez utiliser 'A ' et 'A ', respectivement). –

-1

Je suppose que vous essayez de faire une spécialisation explicite de classe A pour entier. Deviner doit s'écrire template<> Class A<int> ...