如何在C ++中模拟重写父函数(不隐藏)?

时间:2019-01-23 17:07:13

标签: c++ inheritance override

通过阅读此答案(Is it possible to override a function in C++ child class without using virtual keyword to the function in parent class which is abstract?),很明显,您无法覆盖子类的父函数。

尽管如此,我仍然需要类似这样的功能。这是一个非功能性的设置,描述了我要执行的操作。

class Parent {
public:
  Graph createGraph() {
    return new Graph([this](float x){ 
        return this->getY(x); 
    });
  }

  float getY(float x) {
    return sin(x);
  }
}

class Child: public Parent {
public:
  float getY(float x) {
    return x * x;
  }
}

设置的重要方面是我有一个父类,该类具有一个始终引用一个经常被子类重载的函数的函数。来自Java / Javascript领域,我的方法是做上面所看到的,但是看来我在考虑c ++的问题。

我如何模拟(即获得相对相似的功能)这种覆盖形式?

我知道通过不进行干燥,我可以将createGraph复制/设置成两者,并且可以工作。而且如果那是一位经验丰富的c ++开发人员会这样做的方式,那对我来说就足够了。但是现在,我正在寻找一种解决此问题的方法,就像我更像Java的方法一样干。

编辑:这里看来,核心问题是我误解了virtual所做的事情,假设这意味着父类中的函数可能没有定义 (类似于abstract其他语言的功能)。事实并非如此,virtual似乎在做其他允许抽象类的事情,但没有必要。

4 个答案:

答案 0 :(得分:3)

使用CRTP模式。 https://gcc.godbolt.org/z/J_N5Y_

void sink(int);
template<class ChildT>
struct Parent {
    void doStuff(){
        sink(
            static_cast<ChildT*>(this)->getY()
            );
    }
    int getY() {
        return 42;
    }
};
struct Child : Parent<Child> {
    int getY() {
        return 43;
    }
};
struct Child2 : Parent<Child2> {
//Does not want to customize, default is fine.
};
void foo() {
    Child c;
    c.doStuff(); # passes 43
    Child2 c2;
    c2.doStuff(); # passes 42
}

答案 1 :(得分:2)

在父类中,您应该将要覆盖的功能设置为虚拟的,例如:

 class Parent{
 virtual float getY(float x) {
    return sin(x);
  }}

答案 2 :(得分:2)

不确定所提供的链接中没有提供您要查找的内容,但这是在C ++中实现重写的方式。

class Parent
{
public:
    virtual ~Parent() = default;

    Graph createGraph(float x)
    {
        return Graph(getY(x));
    }

    virtual float getY(float x) const
    {
        return sin(x);
    }
};

class Child: public Parent
{
public:
    float getY(float x) const override
    {
        return x * x;
    }
};

int main()
{
    // Play around here with creating a Parent instead of a Child
    //    and/or taking away the virtual keyword to learn how this works
    std::unique_ptr<Parent> thingy = std::make_unique<Child>();
    thingy->createGraph(1.0f);
}

答案 3 :(得分:1)

函数如何调用:

struct Parent{
  virtual void foo(){} // Func(1)
  void call(){
    this->foo();         // (A) call final overrider
    this->Parent::foo(); // (B) call Parent::foo
    }
  };

struct Derived:Parent{
  void foo() override {} // Func(2)
  };

void test(){
  Parent parent; //final overrider of foo is Func(1)
  Derived derived1; //final overrider of foo is Func(2)
  Parent& derived2 = derived; //final overrider of foo is Func(2).

  parent.call()//  At (A) call => Func(1)
               //  At (B) call => Func(1)

  derived1.call()  // At (A) call => Func(2)
                   // At (B) call => Func(1)

  derived2.call()  // At (A) call => Func(2)
                   // At (B) call => Func(1)