开发者

Conflict between providing (optional) functionality and encapsulation?

I need to provide a certain operation on the elements of my class Foo. This operation is specific and weird enough that I don't really want to make it a member function. On the other hand, it works on the internals of the class, which I don't want to expose.

Here is the class:

class Foo {
  typedef std::map<int,double> VecElem;
  std::vector<VecElem> vec_;
 public:
  void Insert(std::size_t index0, int index1, double d);
  // ... other essential functions
};

void Foo::Insert(std::size_t index0, int index1, double d) {
  vec_[index0][index1] = d;
}

The operation I need to support is to map the index1 of each element inserted so far to a new index, according to a given old-to-new index map:

void MapIndex1(const std::map<std::size_t,std::size_t>& old_to_new);

Given how Fo开发者_运维问答o currently stores its elements this means a complete restructuring of the internal data, but this should not be exposed to the user. But also it shouldn't be a member function.

Is this a typical case of a friend non-member function? Are there any other possibilities? I don't really like the concept of a friend non-member function, because this weird function (which might be only temporarily necessary as a workaround for some problem) will still need to be mentioned inside the "official" class body (which is supposed to never change). But I guess I can't get around that?


What about a public nested class to do the work? Then it could have a MapIndex1 function that automatically gains access to the private members of its enclosing class. When you're done, just remove the nested class.

class Foo {
// ...
public:
  void Insert(std::size_t index0, int index1, double d);
  // ... other essential functions
  class Remapper
  {
  public:
    Remapper(Foo& foo) : foo_(foo) { }
    void MapIndex1(const std::map<std::size_t,std::size_t>& old_to_new);
  private:
    Foo& foo_;
  };
};

Foo myFoo;
Foo::Remapper remapper(myFoo);
remapper.MapIndex1(...);


An idea for dealing with this scenario is to add a function like:

void Ioctl(int func, void* params); to your class. This function can then be used as a gateways for all of these hackey temporary scenarios as they arise. They can then be safely removed when the requirement disappears without breaking compatibility (unless of course someone unofficially uses them).

True you do lose type safety but it does provide a nice swiss army knife approach for all such problems.

Internally you can define certain integer func values to call a function and cast the params value to whatever you need.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜