There are quite a few issues with the code you provided:
1. Private Inheritance + Private Function Definitions
You need to declare your methods as public to be able to call them from an external function like RunTest
. Also you probably want to inherit publicly in this case, so you can cast your Test2
class back to a Tester
.
e.g.:
class Tester {
public:
virtual void Validate();
};
class Test1 : public Tester {
public:
void Validate();
};
class Test2 : public Test1 {
public:
void Validate();
};
2. A few recommendations
If you want to override a virtual method in a child class, you can use override
to mark your function as such. That way you'll get a compile-time error in case the function couldn't be overriden (e.g. because of mismatched arguments)
(I'm assuming you meant void Validate() {}
instead of void Validate(...)
)
Also if your classes contain any virtual methods, it's always a good idea to also provide a virtual destructor. (to properly clean up all the members in case it gets deleted by a pointer to its baseclass)
e.g.:
class Tester {
public:
virtual void Validate() {
// TODO
}
virtual ~Tester() = default;
};
class Test1 : public Tester {
public:
void Validate() override {
// TODO
}
};
class Test2 : public Test1 {
public:
void Validate() override {
// TODO
}
};
3. The RunTest()
function will slice the Test2 object
You're passing a Tester
instance to RunTest()
by value.
This will result in the object being sliced, i.e. you'll loose everything stored in the derived objects.
void RunTest(Tester test);
// this
Test2 t2;
RunTest(t2);
// is equivalent to:
Test2 t2;
Test t = t2;
RunTest(t);
so essentially you're calling the RunTest()
method with just a Test
object, not Test2
.
you can fix this by either bassing by reference or by pointer:
void RunTest(Tester& test) {}
// or
void RunTest(Tester* test) {}
Working Example
#include <iostream>
class Tester {
public:
virtual void Validate() {
std::cout << "Tester Validate" << std::endl;
}
virtual ~Tester() = default;
};
class Test1 : public Tester {
public:
void Validate() override {
std::cout << "Test1 Validate" << std::endl;
Tester::Validate();
}
};
class Test2 : public Test1 {
public:
void Validate() override {
std::cout << "Test2 Validate" << std::endl;
Test1::Validate();
}
};
void RunTest(Tester& test) {
test.Validate();
}
int main() {
Test2 t;
RunTest(t);
}
test it on godbolt!