在保留原始方法的同时扩展基类

时间:2016-05-18 16:43:01

标签: c++ inheritance polymorphism

我在创建另一个类的扩展解析器时遇到了一些问题。 这是我所拥有的

的示意图
#include <iostream>

class HeaderType{
public:
  HeaderType(){ this->value1 = 0; }
  double getValue1(){return this->value1;}
  void setValue1(double v){ this->value1 = v; }
protected:
  double value1;
};

class Parser{
public:
  Parser() { this->header = new HeaderType(); }
  virtual ~Parser() {};

  virtual void Parse(){ this->header->setValue1(10); }
  HeaderType* getHeader(){return this->header;}

protected:
  HeaderType* header;
};

class ExtendedHeaderType : public HeaderType{
public:
  ExtendedHeaderType(){ this->value2 = 0; }
  double getValue2(){return this->value2;}
  void setValue2(double v){ this->value2 = v; }
protected:
  double value2;
};

class ExtendedParser : public Parser{
public:
  ExtendedParser() : Parser() { this->header = new ExtendedHeaderType(); }
  virtual ~ExtendedParser(){ delete this->header; }
  ExtendedHeaderType* getHeader(){return this->header;} 
  virtual void Parse(){ Parser::Parse(); this->header->setValue2(20); }
protected:
  ExtendedHeaderType* header;
};

int main()
{
  ExtendedParser* parser = new ExtendedParser();
  parser->Parse();
  ExtendedHeaderType* header = parser->getHeader();
  double value = header->getValue1();  

  std::cerr << "Value: " << value << std::endl;

  return 0;
}

然而,当我这样做时,getValue1()总是返回0,我真的不明白为什么。 当我做解析器 - &gt; Parse()时,它应该调用Parser :: Parse(),它将value1设置为10,当我执行getValue1()时,它应该返回10,而不是0。 我真的不明白为什么会这样。

谢谢。

编辑:当我使用此代码并在main中调用header-&gt; getValue1()时,它返回0,但是调用header-&gt; getValue2()会返回20(如预期的那样)。 / p>

编辑2:实际上,我认为我尝试做的事情是不可能的(或者至少不是以干净的方式)。我想我将不得不创建一个HeaderType和一个ExtendedHeaderType,但它不是HeaderType的派生类,并在ExtendedParser中创建每个类的实例。 IMO最好是能够扩展&#39;一个类,但我认为在内存方面很难,因为首先分配基类,然后是派生类,但是派生类很难修改基类的数据类型class,因为它需要不同的内存量。

1 个答案:

答案 0 :(得分:1)

继承无法重新定义字段以更改其类型 - 因此,您的代码实际上是创建一个类ExtendedParser,其中包含两个字段:

  1. Parser :: HeaderType *
  2. 类型的标头
  3. ExtendedParser :: ExtendedHeaderType *
  4. 类型的标头

    你在value1中得到0的原因是因为ExtendedParser中的Parse在基类上调用Parse来更新Parser :: header的value1。然后它更新ExtendedParser :: header中的value2。

    然后你调用getHeader返回ExtendedParser :: header,实际上,它的value1字段从未被触及,所以你得到0。

    有几种方法可以实现我认为您想要做的事情。一个是不会在ExtendedParser中重新定义头,但是你必须在ExtendedParser :: Parse中将头文件向下转换为ExtendedHeaderType。另一种方法是使用组合而不是继承(参见decorator设计模式),包括Parser和HeaderType。