内部枚举作为基类模板参数

时间:2009-12-12 16:00:00

标签: c++ enums

pragma一次

#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;
    }
};

我想知道是否可以进行这种建设?

3 个答案:

答案 0 :(得分:1)

不,你不能,因为无法转发声明枚举。而且,但不相关,那些构造函数尝试块是一个坏主意。

另见Herb Sutter在http://www.ddj.com/cpp/184401297的文章 - 他对我的态度略逊一筹。无论如何,正如我所说,试块与你的问题无关。

答案 1 :(得分:0)

在我看来,如果你修正错误,你可以。

编辑: 错过了评论,说你想让枚举进入课堂内:你不能这样做。

1)如果你想调用基类的构造函数,那么这是一个模板:

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

2)您无法从构造函数级别的try块返回。你只能通过(重新)投掷退出 - 我假设没有做任何默认的重新抛出。

无论如何,你期望从这些简单类型中得到什么样的例外?

3)在一个地方,您指的是my_data而不是my_data_。但是,如果它们具有默认行为,为什么要实现复制构造函数和赋值运算符? (后者应该返回*this。)

答案 2 :(得分:0)

有一种方法可以将你的枚举放入你的课堂! ......有点

我也希望这样做,我想出的解决方案依赖于枚举总是有一个底层类型的事实(默认情况下,我熟悉的所有编译器都是int)。你必须在基类期望的所有地方指定'int'而不是你的枚举,但你可以将你的枚举传递给这些函数!因此,在您的情况下,您可以执行以下操作:

#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;
    }

};

我无法验证上面的代码是否在没有Token类的情况下编译,但我编译了使用此技术的代码。

干杯