2009-12-12 5 views
1

pragma une fois

#include "stdafx.h" 
#include "Token.h" 

//I would like this enum to be inside class Number 
enum Number_enm {ZERO, ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE}; 

class Number : public Token<Number_enm>//and this template parameter to be Number::Number_enm 
{ 
private: 

public: 
    Number(const Number_enm& num) 
    try: 
    Token(num) 
    { } 
    catch(...) 
    { 
     cerr << "Error in Number::Number(const Number_enm&)."; 
     return; 
    } 

    Number(const char num) 
    try: 
    Token(static_cast<Number_enm>(num & 0xf)) //get number value from char 
    { 
#ifdef DEBUG_ 
    cout << "Converting ctor, from char to Token.\n"; 
#endif 
    } 
    catch(...) 
    { 
     cerr << "Error in Number::Number(const char num)."; 
     return; 
    } 

}; 

#pragma once 

/*Abstract class*/ 
template<class T> 
class Token 
{ 
    typedef T value_type; 
private: 
    value_type my_data_; 
protected: 
    /*Token() 
    try: my_data_() 
    { } 
    catch(...) 
    { 
     cerr << "Error in Token<T>::Token()."; 
     return; 
    }*/ 
    Token(const value_type value) 
     try: 
    my_data_(value) 
    { } 
    catch(...) 
    { 
     cerr << "Error in Token<T>::Token(const value_type&)."; 
     return; 
    } 
    /*Token(const Token& value): my_data(value) 
    { }*/ 
    Token& operator=(const Token& right) 
    { 
#ifdef DEBUG_ 
     cout << "Token& operator=(const Token& right).\n"; 
#endif 
     my_data = right; 
     return my_data; 
    } 
public: 
    T get() const 
    { 
     return my_data_; 
    } 
    T set(const T& new_value) 
    { 
     T old = my_data_; 
     my_data_ = new_value; 
     return old; 
    } 
}; 

Je me demande s'il est possible de faire ce genre de construction?ENUM interne comme paramètre de modèle de classe de base

Répondre

1

Non, vous ne pouvez pas car il n'est pas possible de transmettre une déclaration enum. En outre, mais pas liés, ces blocs d'essai de contructor sont une mauvaise idée.

Voir aussi l'article par Herb Sutter au http://www.ddj.com/cpp/184401297 - il est légèrement moins condamnatoire que moi. Quoi qu'il en soit, comme je l'ai dit, les blocs d'essai n'ont rien à voir avec votre question.

+0

Ok, merci pour votre aide. J'ai lu à propos du bloc try catch dans ctor, dans deux livres et un article (ne me souviens pas lequel, mais c'était un article écrit par Scott Meyers), un livre de Bjarne second par Meyers. Il est catégorique que ce soit une bonne idée, pourquoi dites-vous que c'est une mauvaise idée? –

+0

Eh bien, j'ai lu tous les livres de Meyers et tous les Stroustrup sauf le dernier, et je n'ai jamais lu aucun d'entre eux en disant une telle chose. Le problème avec le bloc catch du constructeur est qu'il ne fait rien d'utile. En C++, vous ne devriez pas utiliser try & catvch mutch de toute façon - vous devriez plutôt utiliser RAII, que Meyers et BS discutent longuement dans tous leurs livres. –

+0

Je vais prendre en compte ce que vous avez dit. N'avez pas vraiment le temps, de parcourir ces livres pour vous envoyer des pages dans lesquelles ils expliquent cette construction. –

0

Il me semble que vous pouvez, si vous corrigez les erreurs.

Modifier:Vous avez manqué le commentaire, en disant que vous voulez que l'énumération soit dans la classe: vous ne pouvez pas le faire.

1) Si vous voulez appeler le constructeur de la classe de base alors c'est un modèle:

Number(const Number_enm& num) 
    try: 
    Token<Number_enm>(num) 

2) Vous ne pouvez pas revenir d'un bloc d'essai au niveau du constructeur. Vous pouvez seulement quitter en (relançant) - je suppose que je ne fais rien par défaut pour ré-émettre.

De toute façon, quelles sont les exceptions que vous attendez de ces types simples?

3) Dans un endroit, vous faites référence à my_data au lieu de my_data_. Mais alors, pourquoi implémenter le constructeur de copie et l'opérateur d'affectation s'ils ont le comportement par défaut? (Ce dernier doit renvoyer *this.)

+0

Tout comme je l'ai dit dans mon précédent commentaire à Neil, j'ai lu à propos de cette construction et comme je suis débutant, j'essaie d'utiliser cette construction pour la mémoriser et me familiariser avec elle.(Bien sûr, dans cet exemple simple, je ne m'attends pas à des exceptions) –

+0

Quoi qu'il en soit, merci pour votre aide –

0

Il existe un moyen de mettre votre énumération dans votre classe! ... genre de

Je voulais faire ça aussi, et la solution que j'ai trouvée repose sur le fait qu'une énumération a toujours un type sous-jacent (int par défaut sur tous les compilateurs que je connais). Vous devez spécifier 'int' au lieu de votre énumération dans tous les endroits que la classe de base attend, mais vous pouvez passer votre énumération dans ces fonctions! Donc, dans votre cas, vous pouvez faire quelque chose comme:

#pragma once 
#include "stdafx.h" 
#include "Token.h" 

class Number : public Token<int> // 'int' instead of 'Number_enm' 
{ 
private: 

public: 
    enum Number_enm {ZERO, ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE}; 

    Number(const Number_enm& num) 
    try: 
    Token(num) // Passed in a Number_enm! 
    { } 
    catch(...) 
    { 
     cerr << "Error in Number::Number(const Number_enm&)."; 
     return; 
    } 

    // I don't know what your Token class does, but I'm guessing that you 
    // need to static_cast to int instead of Number_enm 
    Number(const char num) 
    try: 
    Token(static_cast<Number_enm>(num & 0xf)) //get number value from char 
    { 
#ifdef DEBUG_ 
    cout << "Converting ctor, from char to Token.\n"; 
#endif 
    } 
    catch(...) 
    { 
     cerr << "Error in Number::Number(const char num)."; 
     return; 
    } 

}; 

Je ne peux pas vérifier si le code compile ci-dessus sans la classe de jeton, mais j'ai le code compilé qui utilise cette technique.

Salutations

Questions connexes