2

我需要从一个基类创建多个类(超过 50 个),唯一的区别在于派生类的名称。

例如,我的基类定义为:

class BaseError : public std::exception
{
private:
    int osErrorCode;
    const std::string errorMsg;

public:
    int ec;
    BaseError () : std::exception(), errorMsg() {}

    BaseError (int errorCode, int osErrCode, const std::string& msg)
         : std::exception(), errorMsg(msg)
    {
       ec = errorCode;
       osErrorCode = osErrCode;
    }

    BaseError (const BaseError& other)
        : std::exception(other), errorMsg(other.errorMsg)
    {
        ec  = other.errorCode;
        osErrorCode = other.osErrorCode;
    }

    const std::string& errorMessage() const { return errorMsg; }

    virtual ~BaseError() throw(){}

}

我必须从这个基类创建很多派生类,每个派生类都有自己的构造函数、复制构造函数和虚拟析构函数,目前我正在复制/粘贴代码,在必要时更改名称:

class FileError : public BaseError{
private:
    const std::string error_msg;

public:
    FileError () :BaseError(), error_msg() {}

    FileError (int errorCode, int osErrorCode, const std::string& errorMessage)
        :BaseError(errorCode, osErrorCode, errorMessage){}

    virtual ~FileError() throw(){}
};

问题:是否有某种方法可以使用模板创建这些类,这样就不会重复执行?

4

3 回答 3

7

我想您想创建一个类层次结构,以便您可以在 catch 子句中使用动态调度(依靠编译器找出正确的类型)来实现自定义错误处理。为此,您可以保持BaseError类不变,然后添加一个模板类,然后为其提供多个实例化。考虑一下:

class BaseError : public std::exception
{
private:
    int osErrorCode;
    const std::string errorMsg;

public:
    int ec;
    BaseError () : std::exception(), errorMsg() {}

    BaseError (int errorCode, int osErrCode, const std::string& msg)
         : std::exception(), errorMsg(msg)
    {
       ec = errorCode;
       osErrorCode = osErrCode;
    }

    // ...
};

template <int T>
class ConcreteError : public BaseError {
public:
    ConcreteError () :BaseError(), error_msg() {}

    ConcreteError (int errorCode, int osErrorCode, const std::string& errorMessage)
        :BaseError(errorCode, osErrorCode, errorMessage){}
};

您现在可以设置一些类型定义:

typedef ConcreteError<0> FileError;
typedef ConcreteError<1> NetworkError;
typedef ConcreteError<2> DatabaseError;
// ...

您现在有一个包含三个不同错误类的层次结构。

于 2010-12-13T12:04:46.287 回答
4

如果实现相同,则在其上创建一个枚举和模板。

enum error {
    file_error,
};
template<error e> class my_exception : public BaseError {
    ....
};
typedef my_exception<file_error> file_exception;
于 2010-12-13T12:05:09.467 回答
0

如果实现完全相同,并且您只想为每个类使用不同的名称,那么简单的 typedef 就可以完成您的工作。

如果在实现上略有不同,但在接口上没有,那么您可能需要模板。然后还要考虑基于策略的设计

于 2010-12-13T12:01:55.837 回答