通过阅读此答案(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似乎在做其他允许抽象类的事情,但没有必要。
答案 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)