如何使用 C++ 中的模板编程从基类创建派生类?

发布于 2024-10-07 01:14:33 字数 1223 浏览 8 评论 0原文

我需要从基类创建多个类(超过 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(){}
};

问题: 有没有什么方法可以使用模板创建这些类,这样就不会重复实现?

I need to create a number of classes (more than 50) from a base class, where the only difference is in the names of the derived classes.

For example, my base class is defined as:

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(){}

}

I have to create a lot of derived classes from this base class each having its own constructors, copy constructor and the virtual destructor function, currently I am copying/pasting the code changing the names where necessary :

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(){}
};

Question:
Is there some way to have these classes created using templates so the implementation is not repeated ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

黄昏下泛黄的笔记 2024-10-14 01:14:33

我想您想创建一个类层次结构,以便可以在 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;
// ...

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

I suppose you want to create a class hierarchy so that you can use dynamic dispatch in your catch clauses (relying on the compiler to find out the correct type) to implement custom error handling. You could do this by keeping the BaseError class as it is and then adding a template class for which you then provide multiple instantiations. Consider this:

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){}
};

You can now set up a few type definitions:

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

You now have a hierarchy with three distinct error classes.

一个人的旅程 2024-10-14 01:14:33

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

enum error {
    file_error,
};
template<error e> class my_exception : public BaseError {
    ....
};
typedef my_exception<file_error> file_exception;

If the implementations are identical, make an enum, and template on it.

enum error {
    file_error,
};
template<error e> class my_exception : public BaseError {
    ....
};
typedef my_exception<file_error> file_exception;
玉环 2024-10-14 01:14:33

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

如果实现上有细微差别,但界面上没有,那么您可能需要模板。然后还要考虑基于策略的设计

If the implementation is exactly same, and you just want different name for each class, then simple typedef would do your job.

And if there is slight difference in implementation though not in interface, then you may probably need templates. Then consider also policy based design.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文