0

Currently, I am do a project to implement Unified API. For example for following code

class Helloworld {
 public:
  const std::string & str() const { return str_; }
  std::string & str() { return str_; }
  void str(const std::string & s) { str_ = s; }
 private:
  std::stringstr_;
};

Apparently, all APIs in Helloworld are very strange, I want to add following

const std::string & GetCRefStr() const { return str_; }
std::string & GetMutableStr() { return str_; }
void SetStr(const std::string & s) { str_ = s; }

For this goal, I use cast from base to derived

class HelloworldWrap : public Helloworld {
public:
  const std::string & GetCRefStr() const { return Helloworld::str(); }
  std::string & GetMutableStr() { return Helloworld::str(); }
  void SetStr(const std::string & s) { Helloworld::str(s); }

  // No any member in HelloworldWrap, this class just extend APIs for Helloworld
};

And for using

Helloworld kHW;

HelloworldWrap * GetMutableHelloworld() {
  return static_cast<HelloworldWrap *>(&kHW);
}

const HelloworldWrap & GetCRefHelloworld() {
  return *(static_cast<HelloworldWrap*>(&kHW));
}

int main() {
  GetMutableHelloworld()->SetStr("helloworld");
  // balabala
}

It works ok! Does this approach correct??

mac.ma
  • 703
  • 2
  • 8
  • 22
  • 2
    With `static_cast(&kHW)` you break [*strict aliasing*](https://stackoverflow.com/questions/98650/what-is-the-strict-aliasing-rule). The object `kHW` is *not* a `HelloworldWrap` object, and can't really be used as one. What you do leads to *undefined behavior*. – Some programmer dude Jul 10 '23 at 06:24
  • as long as `HelloworldWrap` has no members this will probably work with most compilers but it is undefined behaviour, making an actual wrapper class rather than deriving would be a better approach – Alan Birtles Jul 10 '23 at 07:08
  • **making an actual wrapper class rather than deriving** looks good, however it will bring performance issue. Consider this case: ```C++ HelloworldWrap * GetMutableHelloworld() { return an instance of HelloworldWrap, Yes, but, where to place it, as class member? For more complicated case, if return value is HelloworldWrap array } ``` I found this issue can not be solved in C++ except **Cast from base to derived** approach – mac.ma Jul 10 '23 at 07:53
  • If it's implemented with inline functions it should be optimised away by the compiler – Alan Birtles Jul 10 '23 at 10:29
  • 1
    This is a use case for composition, not for inheritance. – Andrej Podzimek Jul 10 '23 at 17:20

0 Answers0