c ++继承自虚拟基类

时间:2010-06-24 16:27:55

标签: c++ inheritance virtual

我想做以下事情:

class ErrorBase 
{
  public:
    void SetError(unsigned errorCode)
    {
      mErrorCode = errorCode;
    }

    char const* Explanation(unsigned errorCode) const
    {
      return errorExplanations[errorCode];
    }

  private:
    char const* errorExplanations[];
    unsigned mErrorCode;

};

class MyError : virtual public ErrorBase
{
  public:
    enum ErrorCodes {
      eNone,
      eGeneric,
      eMySpecificError
    };

    MyError() 
    { 

      // I want this to refer to the parent class's attribute, 
      // such that when Explanation() is executed, it uses this
      errorExplanations = {
        "no error",
        "error in MyClass",
        "specific error"
      }
    }
    ~MyError() { }
};

但是我在子类中声明errorExplanations的行上出现以下错误:

  

错误:在'{'标记

之前预期的primary-expression

如何在子类中声明errorExplanations以便我可以实例化一个子节点,并调用myChild.Explanation()并获取子节点构造函数中定义的错误字符串之一?

有关我对constvirtualpublic等的使用的任何建议/更正都表示赞赏,谢谢!

5 个答案:

答案 0 :(得分:2)

要么在构造函数中将错误消息数组传递给基类(语法可能不完美,但希望你能得到这个想法):

class ErrorBase {
  public:
    ErrorBase(char const* errorExplanations[]) {
      this->errorExplanations = errorExplanations;
    }
    ...
  private:
    char const* errorExplanations[];
    ...
};

class MyError : virtual public ErrorBase {
  public:
    ...
    MyError() :
      ErrorBase( {
        "no error",
        "error in MyClass",
        "specific error"
      } )
    { }
    ...
};

或者您使Explanation虚拟并在派生类中提供所需的实现:

class ErrorBase {
  public:
    ...
    virtual char const* Explanation(unsigned errorCode) const = 0;
  protected:
    unsigned mErrorCode;
};

class MyError : virtual public ErrorBase {
  public:
    ...
    MyError() :
      errorExplanations( {
        "no error",
        "error in MyClass",
        "specific error"
      } )
    { }

    virtual char const* Explanation(unsigned errorCode) const {
      return errorExplanations[errorCode];
    }
    ...
  private:
    char const* errorExplanations[];
};

答案 1 :(得分:2)

嗯,有一件事是错的,你不能分配给那样的数组。您只能以这种方式初始化它们。由于您已经在构造函数的初始化部分初始化了数组(为空)(虽然使用默认构造函数为空),因此初始化了数组。

您需要以一种通常分配给数组的方式分配给数组,例如memcpy或for循环。

另一个错误的是你实际上无法访问你试图分配给它的数组。您需要将其公开给具有protected的子类或具有赋值函数。

答案 2 :(得分:2)

这是另一种选择。让基类通过虚函数获取数据数组:

class ErrorBase 
{
  public:
    void SetError(unsigned errorCode)
    {
      mErrorCode = errorCode;
    }

    char const* Explanation(unsigned errorCode) const
    {
      return GetErrorTable()[errorCode];
    }

  private:
    virtual char const **GetErrorTable() const = 0;

  private:
    unsigned mErrorCode;

};

class MyError : virtual public ErrorBase
{
    virtual char const **GetErrorTable()
    {
      static char const *data[] = {
        "no error",
        "error in MyClass",
        "specific error"
      };
      return data;
    }
};

答案 3 :(得分:0)

尝试类似:

class ErrorBase 
{
  public:
    void SetError(unsigned errorCode)
    {
      mErrorCode = errorCode;
    }

    char const* Explanation(unsigned errorCode) const
    {
      return errorExplanations[errorCode];
    }

  private:
    char const** errorExplanations;
    unsigned mErrorCode;

};

class MyError : virtual public ErrorBase
{
  public:
    enum ErrorCodes {
      eNone,
      eGeneric,
      eMySpecificError
    };

    char const* child_strings[] = {"no error", "error in MyClass", "specific error"};

    MyError() 
    { 

      // I want this to refer to the parent class's attribute, 
      // such that when Explanation() is executed, it uses this
      errorExplanations = child_strings;
    }
    ~MyError() { }
};

让您的父类只包含一个指针,让您的子类创建并初始化该数组,然后使指针指向您孩子的构造函数中的数组。

答案 4 :(得分:0)

另一个选择:创建Explanation(unsigned) const函数virtual,以便派生类管理自己的查找错误消息的机制:

class ErrorBase 
{
public:
    virtual ~ErrorBase() { }

    void SetError(unsigned errorCode)
        : mErrorCode(errorCode)
    {
    }

    char const* Explanation() const { return this->Explanation(mErrorCode); }

    virtual char const* Explanation(unsigned errorCode) const
    {
        return errorExplanations[errorCode];
    }

private:
    unsigned mErrorCode;
};

class MyError : virtual public ErrorBase
{
public:
    enum ErrorCode {
        eNone = 0,
        eGeneric = 1,
        eMySpecificError = 2
    };

    MyError(ErrorCode c)
        : ErrorBase(static_cast<unsigned>(c))
    {
    }

    virtual ~MyError() { }

    virtual char const* Explanation(unsigned errorCode) const;
};

然后将MyError错误代码的错误字符串编译到目标文件中:

// MyError.cpp
static const char* s_errorExplanations[] = {
        "no error",
        "error in MyClass",
        "specific error"
    };

char const* MyError::Explanation(unsigned errorCode) const
{
    return s_errorExplanations[errorCode];
}