Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/162.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++_Class_Oop_Inheritance_Abstract Class - Fatal编程技术网

在C++中将实现注入到类中

在C++中将实现注入到类中,c++,class,oop,inheritance,abstract-class,C++,Class,Oop,Inheritance,Abstract Class,考虑以下示例: class A{ public: virtual void hello() = 0; }; class B: public A{}; class C { public: void hello(){ cout<<"Hi"; } }; class D: public B, public C{}; 我的想法是,我想通过C将hello的实现注入到D中。这似乎不起作用,除非我让C也从A继承。因为这会导致菱形继承,所以我最终使用虚拟继承 在

考虑以下示例:

class A{
public: virtual void  hello() = 0;
};

class B: public A{};

class C {
    public: void hello(){
        cout<<"Hi";
    }
};
class D: public B, public C{};
我的想法是,我想通过C将hello的实现注入到D中。这似乎不起作用,除非我让C也从A继承。因为这会导致菱形继承,所以我最终使用虚拟继承

在不干扰抽象类a和B的情况下,是否有其他方法可以强制实现到派生类中


编辑:我想要一个不需要在D中显式编写代码的解决方案。这是因为,我有很多类,比如D,都有相同的实现,这就是为什么我想把这个实现推到它们继承的某个类。

当你需要将外部方法注入类层次结构时,你可以考虑静态继承/策略类。请注意,注入该方法通常意味着该方法与类层次结构中的现有虚拟名称不相同。如果该方法与类层次结构中的现有虚拟名称相同,则必须使用虚拟继承或使用scope::显式调用,或将其插入类层次结构中。我在这里调用了externalHello方法

其他选项也可以很好地工作,但它们在概念上更多地指向这样一个事实:注入的方法实际上不是一个抽象方法,可以在这个类层次结构之外使用,但首先应该是它的一部分

class A
{
    public: 
        virtual void  hello() = 0;
};

class B: public A 
{
    public: 
    void hello()
    {
        cout<<"Hi from B" << endl;
    };

};

template<typename T> class C1 
{
    public: 
    void injectedMethodUnrelatedToClassHierarchy()
    {
        cout<<"Hi from C1 with unrelated method" << endl;
    };    
    void externalHello() 
    {
        static_cast<T*>(this)->hello(); // will still call hello in B
        injectedMethodUnrelatedToClassHierarchy(); // this will call hello here
    };
};

class D: public B, public C1<D>{};

您可以将C重写为一个模板类,该类继承自它的模板参数,然后从C派生D

template <class Base>
class C : public Base {
    public: void hello(){
        cout<<"Hi";
    }
};
class D: public C<B> {};
这可能有用

#include<iostream>
using namespace std;

class A
{
 public: 
    virtual void  hello() = 0;
};

class C {
   public: void hello(){
    cout<<"Hi\n";
  }
};

template<typename T>
class B: public A, public T
{
  public:   
    void hello() override{ //override A::hello()
    //do other staff

    T::hello(); // call C::hello()
   }
};



 class D: public B<C>{

  };

 int main()
 {
  D d;
  d.hello();
  return 0;
 }

你想要D中的哪个版本?B::hello或C::hello?如果你想在D中使用B::hello,你可以简单地在DI中使用B::hello。我想在D中实现A::hello。你的意思是在D中实现A::hello并在实现中调用C::hello?是的。但实际上没有用D显式地编写任何代码。仅仅通过使用继承。例如,我用虚拟继承解决了这个问题。我想知道是否还有其他方法。因此,注入的方法不可能重写类层次结构中的某个方法?然后,您必须将该类插入到类层次结构中,并选择要执行该操作的位置,使用模板可以更容易地选择D Drmmr建议的位置,而不是使应该具有该函数的类从跨不同类层次结构的函数容器派生。取决于你在概念上喜欢什么。
#include<iostream>
using namespace std;

class A
{
 public: 
    virtual void  hello() = 0;
};

class C {
   public: void hello(){
    cout<<"Hi\n";
  }
};

template<typename T>
class B: public A, public T
{
  public:   
    void hello() override{ //override A::hello()
    //do other staff

    T::hello(); // call C::hello()
   }
};



 class D: public B<C>{

  };

 int main()
 {
  D d;
  d.hello();
  return 0;
 }