I am trying to refactor and rewrite some parts of a legacy library. This library has base classes with same variable names repeatedly declared and used in derived classes (caused by copy/paste programming). For example I have:
class MyBaseClass
{
public:
int m_nVar;
protected:
virtual void MyFunc()
{
m_nVar++;
}
public:
MyBaseClass()
{
m_nVar = 1;
}
};
class MyDerivedClass : public MyBaseClass
{
public:
int m_nVar;
protected:
virtual void MyFunc()
{
m_nVar++;
}
public:
MyDerivedClass ()
{
m_nVar = 2;
}
};
This situation causes me problems because I need to move some functionality I need to a more general base class so that MyBaseClass can be derived from it.
class MyNewBaseClass
{
public:
int m_nVar;
protected:
virtual void MyFunc()
{
m_nVar++;
}
public:
MyNewBaseClass()
{
}
};
class MyBaseClass : public MyNewBaseClass
{
public:
MyBaseClass()
{
m_nVar = 1;
}
};
class MyDerivedClass : public MyBaseClass
{
public:
int m_nVar;//this causes me problems, I need to get notifications on occurrences of such situations
public:
MyDerivedClass ()
{
m_nVar = 2; //this assignments has no effect on MyNewBaseClass::m_nVar
}
};
After I make my modifications MyFunc() in a MyDerivedClass instance does not work as the original code (first run on original causes m_nVar = 3, but in my modified code it becomes m_nVar = 2).
I need some kind of compiler error or warning to notify me of all occurrences of such situations or any other solutions to accomplish what I need.
What do you suggest which works in Visual Studio (VC++)?
Related
I've been trying to find an answer to this question but I couldn't (I don't even know how to properly formulate this) so I decided to write my first post ever on StackOverflow =).
The context is the following:
I have this parent class:
class Parent
{
public:
Parent(){};
void foo(void)
{
//Do some common things
bar();
//Do some more common things
};
protected:
virtual void bar(void) = 0;
};
And I want to create an indefinite amount of derived Childs:
class Child1 : public Parent
{
public:
Child1() : Parent(), child1Variable(0) {};
protected:
virtual void bar(void) = 0;
private:
uint32_t child1Variable;
};
class Child2 : public Parent
{
public:
Child2() : Parent(), child2Variable(0) {};
protected:
virtual void bar(void) = 0;
private:
uint32_t child2Variable;
};
.
.
.
class ChildN : public Parent
{
public:
ChildN() : Parent(), childNVariable(0) {};
protected:
virtual void bar(void) = 0;
private:
uint32_t childNVariable;
};
The reason being mainly not repeating the code in Parent's foo()
Then I would like to create my final instantiable classes as, for instance:
class ExampleFinal : public Child1, public Child3, public Child27
{
//How to define Child1::bar(), Child3::bar() and Child27::bar() ??
private:
void bar(void); //????
};
So the questions are:
How can I define the method for (abusing notation) ExampleFinal::Child1::bar, ExampleFinal::Child3::bar, ...
Am I so stuck on this that I'm overlooking a much simpler solution?
The final goal is being able to do something like:
ExampleFinal test;
test.Child1::foo(); //should end up on "ExampleFinal::Child1::bar"
test.Child3::foo(); //should end up on "ExampleFinal::Child3::bar"
Thanks!
Implementing ExampleFinal::bar() (side-note: bar(void) is a C-ism which has no use in C++) will override all of the bars you have declared at once. If you want to have different versions, you'll need to interpose another layer of classes:
struct GrandChild1 : Child1 {
void bar() override { /*...*/ }
};
// And so on...
struct ExampleFinal : GrandChild1, GrandChild3, GrandChild27 {
// Nothing needed here.
};
Then the behaviour you described will work. Be aware, though, that your inheritance graph means that an ExampleFinal has one Parent subobject per Child. This is not an issue in itself but might not model what you want -- maybe you need virtual inheritance here, but beware of the rabbit hole.
If you want to keep the overrides for all ChildN::bars inside ExampleFinal, you can add tag-dispatching to discern them, at the cost of one more virtual call:
struct Parent {
void foo() {
bar();
};
protected:
template <class Child>
struct tag { };
virtual void bar() = 0;
};
struct Child1 : Parent {
protected:
virtual void bar(tag<Child1>) = 0;
void bar() final override {
return bar(tag<Child1>{});
}
int child1Var;
};
struct Child2 : Parent {
protected:
virtual void bar(tag<Child2>) = 0;
void bar() final override {
return bar(tag<Child2>{});
}
int child2Var;
};
struct ExampleFinal : Child1, Child2 {
protected:
using Parent::tag;
void bar(tag<Child1>) final override {
std::cout << "Child1::bar\n";
}
void bar(tag<Child2>) final override {
std::cout << "Child2::bar\n";
}
};
Note that the bar() to bar(tag<ChildN>) bridge can easily be hidden behind a macro. If you want to avoid the cost of the second virtual call, a CRTP can also be applied here.
I am no doubt overlooking something basic but my implementation is obviously flawed.
I am trying to require a derived classes to implement a method being called in a base class.
class IClock
{
public:
virtual void OnTimeExpired() = 0;
}
class Clock : public IClock
{
... // ABC not implemented
}
class Application : public Clock
{
... // ABC not implemented
}
class DerivedApp : public Application
{
public:
virtual void OnTimeExpired() { ... }
}
I rarely use pure ABCs, so I thought by not defining the pure virtual method in Clock and Application, it would require all derivatives of Application to define the OnTimeExpired() method.
I discovered this will compile and link (MSVS-2017) and if DerivedApp does not implement the method, the Clock object will call an undefined method and crash.
Why does this compile without the pure virtual method being implemented?
How do I force derived Application classes to implement the OnTimeExpired() method?
EDIT: The crash was due to unrelated error - I apologize. Nevertheless the questions I ask are still applicable.
As requested here is a complete, buildable, minimal example:
IClock.h:
#pragma once
class IClock
{
public:
virtual void OnClockTime() = 0;
};
Clock.h:
#pragma once
#include "IClock.h"
class Clock : public IClock
{
public:
Clock();
virtual ~Clock();
void ClockUpdate();
virtual void OnClockTime();
private:
float elapsed_time;
};
Clock.cpp:
#include "Clock.h"
Clock::Clock()
: elapsed_time(0.0f)
{
}
Clock::~Clock()
{
}
void Clock::ClockUpdate()
{
elapsed_time += 0.0000001f; // small ticks for testing
if (elapsed_time >= 1.0f) {
OnClockTime();
elapsed_time -= 1.0f;
}
}
void Clock::OnClockTime()
{}
ApplicationBase.h
#pragma once
#include "Clock.h"
class ApplicationBase : public Clock
{
public:
ApplicationBase();
virtual ~ApplicationBase();
virtual void Init(){}
virtual void Run(){}
protected:
bool app_run;
};
ApplicationBase.cpp:
#include "ApplicationBase.h"
ApplicationBase::ApplicationBase()
: app_run(false)
{
}
ApplicationBase::~ApplicationBase()
{
}
DerivedApp.h:
#pragma once
#include "ApplicationBase.h"
class DerivedApp : public ApplicationBase
{
public:
DerivedApp();
virtual ~DerivedApp();
virtual void Init() {}
virtual void Run();
//virtual void OnClockTime();
};
DerivedApp.cpp:
#include "DerivedApp.h"
#include <iostream>
DerivedApp::DerivedApp()
{
}
DerivedApp::~DerivedApp()
{
}
void DerivedApp::Run()
{
app_run = true;
while (app_run) {
ClockUpdate();
}
}
//void DerivedApp::OnClockTime()
//{
// static int counts(0);
// std::cout << "Tick..." << std::endl;
// counts++;
// if (counts >= 10)
// app_run = false;
//}
main.cpp
#include "DerivedApp.h"
class App : public DerivedApp
{
public:
App(){}
~App(){}
};
int wmain(int argc, wchar_t * argv[])
{
App *app = new App();
app->Init();
app->Run();
delete app;
}
Thanks to those who requested a minimal working example, I built it and it works exactly as I had hoped. The complier will complain about no instantiation of the ABC in the App class. If I remove the comments from DerivedApp::OnClockTime() it compiles and runs the way I wish. Obviously my actual code is not following this model as I thought, so now I need to reexamine where I went wrong. Thanks.
There is no keyword in C++ that forces a class to override some method. However, by making OnTimeExpired() pure virtual you're making IClock an abstract class. Any classes deriving from IClock that do not implement OnTimeExpired() will automatically become an abstract class too, thus not allowing you to create objects of these classes. This means that your code as-is is completely legal unless you try to make objects of these classes
class AbstractBase {
public:
virtual void someFunc() = 0; // Purely Virtual
};
class AbstractDerived : public AbstractBase {
public:
void someOtherFunc();
// Still abstract because the following is not declared-defined
// void someFunc() override { ... }
};
class NonAbstractDerivedA : public AbstractBase { // Derived From Base
public:
void someFunc() override { /* do this class's implementation*/ }
};
class NonAbstractDerivedB : public AbstractDerived { // Derived From AbstractDerived
public:
void someFunc() override { /* do this class's implementation*/ }
};
uses:
#include "above"
int main() {
AbstractBase base; // compiler error
AbstractDerived derived; // compiler error
NonAbstractDerivedA derivedA; // should be okay
NonAbstractDerivedB derivedB; // should be okay
return 0;
}
Let a class hierarchy :
class Base { virtual ~Base() throw(); };
class DerivedA : public Base { };
class DerivedB : public Base { };
I would like to have some code specific to each of these derived classes. However that code also being specific to the application that makes use of this class hierarchy, I do not want to embbed this derived-class-specific code into these derived classes. To avoid doing so, I thought about writing free functions :
void DerivedASpecificWork( DerivedA da );
void DerivedBSpecificWork( DerivedB db );
However, when given an instance of a derived class through a reference/pointer to a Base, I do not have access to the actual type of the instance, and thus cannot call the proper Derived*SpecificWork() function.
I would like to know if there is nome kind of design pattern that would allow me to call a derived-class-specific function without knowing the actual type of the instance, i.e having the same mechanism as virtual functions provide, but without having these virtual functions that would require me to embbed application-specific code into that class hierarchy.
Actually, why I want to do that is to provide informations about an exception that occured within a natively implemented function called by a Lua script. Each exception carrying its own set of information, the way I want to represent the error within the script depends on the type of the exception. I could create a pure virtual method in the base class that would be implemented by derived classes, but this would require me to embbed Lua-related code into my exception hierarchy, which I do not want to do since the Lua is specific to one of the application using that exception hierarchy.
Also I cannot use C++11.
Thank you.
May be Brigde pattern can help you.
This pattern can be used when you want to avoid a permanent binding between an abstraction and it's implementation.
(I don't see your comment about your restriction in using c++11, but you can remove std::unique_ptr, std::move and override keyword)
class AppSpecificImp
{
public:
virtual void DoWork() = 0;
};
class Base
{
public:
virtual ~Base() throw();
virtual DoWork() = 0;
};
class DerivedA : public Base
{
public:
DerivedA(std::unique_ptr<AppSpecificImp> appImp)
: imp(std::move(appImp))
{
}
void DoWork() override
{
// DerivedA specific code
imp->DoWork();
}
private:
std::unique_ptr<AppSpecificImp> imp;
};
class DerivedB : public Base
{
public:
DerivedB(std::unique_ptr<AppSpecificImp> appImp)
: imp(std::move(appImp))
{
}
void DoWork() override
{
// DerivedB specific code
imp->DoWork();
}
private:
std::unique_ptr<AppSpecificImp> imp;
};
Edit to show Visitor pattern usage:
With visitor pattern you can do what you want but with more Effort.
class Visitor
{
public:
virtual void VisitDerivedA(DerivedA* object) = 0;
virtual void VisitDerivedB(DerivedB* object) = 0;
};
class Base
{
public:
virtual void Visit(Visitor* visitor) = 0;
};
class DerivedA : public Base
{
public:
virtual void Visit(Visitor* visitor)
{
visitor->VisitDerivedA(this);
}
};
class DerivedB : public Base
{
public:
virtual void Visit(Visitor* visitor)
{
visitor->VisitDerivedB(this);
}
};
class AppSpecificVisitor : public Visitor
{
public:
void VisitDerivedA(DerivedA* object)
{
// Do any work related to DerivedA class
}
void VisitDerivedB(DerivedB* object)
{
// Do any work related to DerivedB class
}
}
int main()
{
AppSpecificVisitor myVisitor;
Base* myBase = // any class in your hierarchy
myBase->Visit(&myVisitor);
}
As I said in comments with Visitor pattern you can add new functionally without changing the main hierarchy(Base->Derived types). You just define a new visitor implementation and write your logic for every class in main hierarchy. In your example you can pack app specific logic in an object and reference that in your derived objects that is an easier approach.
Why not using a new set of hierarchy for application specific implementation ?
class AppBase
{
public:
virtual ~AppBase() throw();
virtual void work_with_app() = 0;
};
class Base
{
public:
Base(AppBase& app) : m_app(app) {}
virtual ~Base() throw();
protected:
AppBase& m_app;
};
class DerivedA : public Base { DerivedA(AppBase& app) : Base(app) {} };
class DerivedB : public Base { DerivedA(AppBase& app) : Base(app) {} };
// Application specific implementation :
class AppLuaSpecific : public AppBase
{
public:
void work_with_app() { /* Lua app specific */ }
};
This way, your 1st hierarchy : Base, DerivedA, DerivedB can live without knowing anything about the app specific code implemented in AppLuaSpecific.
You can implement your own app-specific dispatch as follows (check it live on Coliru):
#include <iostream>
#include <typeinfo>
struct Base { virtual ~Base() {} };
struct DerivedA : public Base { };
struct DerivedB : public Base { };
namespace AppSpecific
{
template<class F>
void dispatch(const Base& b)
{
const std::type_info& t = typeid(b);
if ( t == typeid(DerivedA) )
F::doit(static_cast<const DerivedA&>(b));
else if ( t == typeid(DerivedB) )
F::doit(static_cast<const DerivedB&>(b));
}
struct Foo
{
static void doit(const DerivedA& da) { std::cout << "Foo(DerivedA)\n"; }
static void doit(const DerivedB& db) { std::cout << "Foo(DerivedB)\n"; }
};
struct Bar
{
static void doit(const DerivedA& da) { std::cout << "Bar(DerivedA)\n"; }
static void doit(const DerivedB& db) { std::cout << "Bar(DerivedB)\n"; }
};
} // namespace AppSpecific
int main()
{
DerivedA da;
DerivedB db;
Base& b1 = da;
Base& b2 = db;
AppSpecific::dispatch<AppSpecific::Foo>(b1);
AppSpecific::dispatch<AppSpecific::Foo>(b2);
AppSpecific::dispatch<AppSpecific::Bar>(b1);
AppSpecific::dispatch<AppSpecific::Bar>(b2);
}
I am implementing a decorator pattern following the example in here:
Class I: is the interface class, common to both core class and decorator base class
Class A: is the core class
Class D: is the decorator base class
Classes X, Y, Z: inherit from the decorator base class and extend functionality of the core class dynamically
There is one method in class A (A::endTraining()), which is triggered at the end of a timer variable (also present in class A). This method needs to call some member of X, Y and Z classes.
Is it possible? Is it good practice? How?
For example, is creating a mechanism to register the pointers-to-XYZ::endTraining in class A a correct approach?
(showing only relevant bits)
typedef void (D::*pCallback_fn)(void);
class I
{
public:
virtual void endTraining() = 0;
virtual void regTrainingCallbacks(pCallback_fn ptrFn) = 0;
};
class A: public I {
public:
void endTraining() {
//do stuff
//then do stuff in D (and its derivatives)
// by iterating through fnList
}
void regTrainingCallbacks(pCallback_fn ptrFn)
{
fnList.push_back( ptrFn );
}
private:
std::list<pCallback_fn> fnList;
};
class D: public I {
public:
D(I *inner) {
m_wrappee = inner;
}
void regTrainingCallbacks(pCallback_fn ptrFn)
{
m_wrappee->regTrainingCallbacks(ptrFn);
}
private:
I *m_wrappee;
};
class X /*,Y,Z*/ : public D {
public:
X(I *core): D(core)
{
D::regTrainingCallbacks( this->*endTraining() ); //
}
private:
void endTraining(){
//do stuff when called by A::endTraining() through D
}
};
What can be done instead?
Addressing one fault in the original design, in which the 'trainer' (the entity registering training callbacks) must be a callback in itself (is there any reason the notifier - former class A - must be a callback itself?).
I changed the class names to put into evidence their responsibilities.
The MainTrainingProcess replaces the original class A (instances of which would have been wrapped by D-es) and the D itself.
class EndTrainingListener
{
public:
virtual ~EndTrainingListener() { }
virtual void endTraining()=0;
};
class ITrainingProcess
{
public:
virtual ~ITrainingProcess() { }
virtual void regTrainingCallbacks(EndTrainingListener* callback) = 0;
};
class MainTrainingProcess : public ITrainingProcess {
public:
virtual ~MainTrainingProcess() {
// destroy other resources used during training
}
virtual void regTrainingCallbacks(EndTrainingListener* callback) {
this->listeners.push_back(callback);
}
void train() {
// do training stuff
// ...
// do my specific actions at the end of training
// ...
// finish by notifying all listeners
this->atEndTraining();
}
protected:
void atEndTraining() {
for(auto l : this->listeners) {
l->endTraining();
}
}
std::list<EndTrainingListener*> listeners;
};
class X /*Y, Z*/ : public EndTrainingListener {
public:
virtual ~X();
virtual void endTraining() {
// do specific stuff
}
};
My question might not be too correct... What I mean is:
class MyClass
{
public:
MyClass()
{
}
virtual void Event()
{
}
};
class FirstClass : public MyClass
{
string a; // I'm not even sure where to declare this...
public:
FirstClass()
{
}
virtual void Event()
{
a = "Hello"; // This is the variable that I wish to pass to the other class.
}
};
class SecondClass : public MyClass
{
public:
SecondClass()
{
}
virtual void Event()
{
if (a == "Hello")
cout << "This is what I wanted.";
}
};
I hope that this makes at least a little sense...
Edit: _This changed to a.
What you need to do is make SecondClass inherit from FirstClass and declare _This as protected.
class FirstClass : public MyClass
{
protected:
string _This;
public:
and
class SecondClass : public FirstClass
What you got doesn't make sense because classes can only see members and functions from their parents (MyClass in your case). Just because two class inherit from the same parent does not mean they have any relation or know anything about each other.
Also, protected means that all classes that inherit from this class will be able to see its members, but nobody else.
I guess that you need something like this (for a sake of simplicity, I've omitted all the unnecessary code):
class Base{
public:
~Base(){}
protected:
static int m_shared;
};
int Base::m_shared = -1;
class A : public Base{
public:
void Event(){
m_shared = 0;
}
};
class B : public Base{
public:
void Event(){
if (m_shared == 0) {
m_shared = 1;
}
}
};
int _tmain(int argc, _TCHAR* argv[])
{
A a;
B b;
a.Event();
b.Event();
return 0;
}
To explain above, I'll explain the static data members:
Non-static members are unique per class instance and you can't share them between class instances. On the other side, static members are shared by all instances of the class.
p.s. I suggest that you read this book (especially Observer pattern). Also note that above code is not thread-safe.