1

我有一个A看起来像的抽象类

class A {
public:
  virtual vector<char> marshall() = 0;
  virtual void unmarshall(vector<char> raw) = 0;
};

继承自的类A会覆盖这两种方法:特别是会unmarshall改变子类的内部状态。

例如

class B : public A {
  int someImportantInt;

  vector<char> marshall() {
    vector<char> r;
    r.push_back(someImportantInt);
    return r;
  }

  void unmarshall(vector<char> raw) {
    someImportantInt = raw[0];
  }
};

B现在,我认为突变是邪恶的,另外我们必须实例化,然后才调用的事实unmarhsall看起来像代码味道。

一种选择是有一个带有 a 的构造函数vector<char>,但我不知道有一种方法可以强制子类这样做。

编辑:

umarshall构造方法的动机是 B 的状态一旦被调用就不会改变。因此,我们可以将其从构造函数中移除unmarshallA替换为B带有vector<char>.

IE

class B : public A {
  int someImportantInt;

  B(const vector<char>& raw) : someImportantInt(raw[0]) {}
  vector<char> marshall(); 
}

正如我所看到的,这里的问题是没有强制子类声明一个接受vector<char>.

我在这里有什么选择?

4

1 回答 1

0

您可以使用执行编组和解组的模板 Marshaller 类。然后在类中使用 Marshaller 类型的数据成员,而不仅仅是 int。然后在 Marshaller 的构造函数中,您将初始化一个向量成员,因此没有类需要知道它。像这样的东西:

template <class T>
class Marshaller {
  T real_data;
  vector<char> marshalled_data;
  Marshaller ();
  Marshaller (Marshaller&);
 public:
  Marshaller (T& t) :real_data(t) {
    // Do whatever with marshalled_data.
  }
  void marshall () {
    // Fill me in.
  }
  void unmarshall () {
    // Fill this in.
  }
  vector<char> rawData () {
    return marshalled_data;
  }
  bool isMarshalled () {
    return marshalled_data.size() > 0;
  }
  T& data () {
    return real_data;
  }
};

class B {
  Marshaller<int> someImportantInt;
 public:
  B () :someImportantInt(0) {}
  B (int i) :someImportantInt(i) {}
  int getImportantInt () {
    return someImportantInt.data();
  }
  vector<char> getRawInt () {
    return someImportantInt.raw data();
  }
  void unmarshall () {
    someImportantInt.unmarshall();
  }
};

我希望你理解这个想法足以给你一个起点。您可能会向 Marshaller 添加更多功能,以处理诸如 operator=() 之类的数据何时被编组或不被编组的事情。我不知道从哪里开始,因为我不确定你想要什么。这是我最好的猜测,当然你可以随意修改它。

于 2013-07-04T20:19:03.190 回答