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;
// ...

これで、3 つの異なるエラー クラスを持つ階層ができました。

于 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 に答える