Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/151.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 用一个很好的理由选兄弟姐妹班?_C++_Polymorphism_Siblings_Static Cast - Fatal编程技术网

C++ 用一个很好的理由选兄弟姐妹班?

C++ 用一个很好的理由选兄弟姐妹班?,c++,polymorphism,siblings,static-cast,C++,Polymorphism,Siblings,Static Cast,我有一个基本类和许多派生类(即DerivedX)作为生产代码。 在不涉及这些类的情况下,我创建了一个从Base派生的BaseExt类,以便为测试目的操作内部数据 +-----------+ +-----------+ | Base + <- - - - - | BaseExt | +-----------+ +-----------+ /|\ | +-----------+ | DerivedX + +-------

我有一个基本类和许多派生类(即DerivedX)作为生产代码。 在不涉及这些类的情况下,我创建了一个从Base派生的BaseExt类,以便为测试目的操作内部数据

+-----------+            +-----------+
| Base      + <- - - - - | BaseExt   |
+-----------+            +-----------+
   /|\
    |
+-----------+
| DerivedX  +
+-----------+
这对我来说很直观

    std::shared_ptr<Base> p = std::make_shared<Derived1>();
    auto d1 = p->data(); // 0
    std::static_pointer_cast<BaseExt, Base>(p)->inject_data(10);
    auto d2 = p->data(); // 10
std::shared_ptr p=std::make_shared();
自动d1=p->data();//0
std::static_pointer_cast(p)->inject_data(10);
自动d2=p->data();//10
基线:我不想更改我的生产代码(即Base和DerivedX)

当然,我可以扩展Derived1来做同样的工作,但是我有很多这样的派生类,它们为一个简单的任务添加了太多的代码

问题是

  • 对于这个用例,将其转换为兄弟类是否合理
  • 如何使它安全?(例如,同级类中没有属性)
  • 任何更好、更简洁的解决方案(除了修改基类和Derievedx类)
    • 模板呢

      template<typename T>
      struct TestableDerived : T {
      
          inject_data(int data) {
              _data = data;
          }
      
          static std::shared_ptr<Base> createAndInjectData(int data) {
              std::shared_ptr<TestableDerived<T>> ptr = std::make_shared<TestableDerived<T>>();
              ptr->inject_data(data);
              return ptr;
          }
      }
      

      更安全的方法是为此创建一个
      friend
      函数。为什么您将类型为Derived1的实例强制转换为其他类型的BaseExt很直观。如果BaseExt有一些数据成员呢?@Zefick基类中有一个friend函数?但是修改基类和Derievedx类将是最后的选择option@marcinj是的,这正是我的问题!在一定条件下进行此类铸造是否合理?i、 e.兄弟类中没有额外的属性。我认为没有一种安全的方法可以在不修改
      Base
      /
      DerivedX
      的情况下进行黑客攻击。
      template<typename T>
      struct TestableDerived : T {
      
          inject_data(int data) {
              _data = data;
          }
      
          static std::shared_ptr<Base> createAndInjectData(int data) {
              std::shared_ptr<TestableDerived<T>> ptr = std::make_shared<TestableDerived<T>>();
              ptr->inject_data(data);
              return ptr;
          }
      }
      
      struct BaseExt : virtual Base {
          void inject_data(int data) { _data = data; }
      }
      
      template<typename T>
      struct TestDerived<T> : virtual T, virtual BaseExt {}
      
      void doSomeTesting() {
          std::shared_ptr<TestDerived<DerivedX>> p1 = std::make_shared<TestDerived<DerivedX>>();
          std::shared_ptr<DerivedX> p2 = p1;
          std::shared_ptr<BaseExt> p3 = p1;
      
          assert(p1->data()==0);
          assert(p2->data()==0);
          assert(p3->data()==0);
      
          p3->inject_data(10);
      
          assert(p1->data()==10);
          assert(p2->data()==10);
          assert(p3->data()==10);
      }