Reputation: 10938
From reading this answer (Is it possible to override a function in C++ child class without using virtual keyword to the function in parent class which is abstract?) it is apparent that one can not override a parent function from a child class.
Nevertheless, I need something that functions like this. Here's a non functional setup that describes what I'm trying to do.
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;
}
}
The important bits of my setup are that I have a parent class which has a function that consistently references a function that is often overloaded by child classes. Coming from Java/Javascript land, my approach would be to do what you see above, but it appears I'm thinking about this incorrectly for c++.
How can I simulate (ie get relatively similar functionality) to this form of overriding?
I know that by not being DRY I could copy/paset createGraph
into both, and it would work. And if that's the way an experienced c++ dev would do it, than it's good enough for me. But right now, I'm looking for a way to approach this problem that is as DRY as my more java-like way.
EDIT: it would appear the core issue here is that I misunderstood what virtual
does, assuming it meant there could be no definition of the function in the parent class (similar to abstract functions in other languages). That is not the case, virtual appears to do something else which allows for abstract classes, but does not necessitate them.
Upvotes: 1
Views: 131
Reputation: 4010
Not sure what you are looking for that has not already been provided in the link you gave, but this is how you would implement overriding in 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);
}
Upvotes: 2
Reputation: 18051
How work function call:
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)
Upvotes: 1
Reputation: 27664
use CRTP pattern. 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
}
Upvotes: 3
Reputation: 2080
in the parent class you should make the functions you wanna override as virtual eg:
class Parent{
virtual float getY(float x) {
return sin(x);
}}
Upvotes: 2