Hi
When I try to make new class, which inherited from another class I found, as I understand, a mistake in working a compiled code.
Code Example:
char s[1024]; class Parent{ public: Parent(){ vMethod(); }; virtual void vMethod(){ sprintf(s,"Parent virtual method"); }; }; class Child: Parent{ public: Child(){ vMethod(); }; virtual void vMethod(){ sprintf(s,"Child virtual method"); }; }; int main(void){ Child* c = new Child(); ...
So, what happends. At this code the methos and constructor calling should to be the next: 1. Calling the Parent constructor, which call overrided vMethod of Child class 2. Calling the Child constructor, which again call overrided vMethod of Child class.
But the Parent construcor calls Parent vMethod and the Child constructor calls Child vMethod. So clasic overriding is works not correct.
The clasic construction on overrided method shoilt to looks like: override void vMethod(){} or virtual void vMethod() override{} but none of this code construction dosn't work.
So it's a error in compilator or I shoult to use another construction for correct overriding virtual class methods.
Thanks.
Fortunately what you claim you would like to happen does not actually happen as it would make a lot of code that has already been written not work (as well as create what could only be described as "undefined behavior".
This not a compiler bug.
One way to look at this is that construction happens from base class to the derived class(es). How can the base class call ANYTHING in a derived class if the derived class has not been constructed yet? That is what you are asking to happen and this is not something that would make sense.
Also on Destruction, you could have an issue that a base class tries to call a function in a derived class AFTER the destructor has been called.
Thanks for answer.
If compiler was written like this, when have it your way. But this way is violate an a foundation of object-oriented implementation.
For methods which shouldn't be overridden present a simple class methods The main purpose of virtual methods is posibility of it overriding.
For hiding simple methods in child class in modern implementation of c++ present new operator. In this case classes works like this time. The parent class has one method and it calls when it calls from parent class, and child has second method with same name and it calls when it calls from child class. It not an overriding.
I understand if this way was used because a lot of code use this way, but it this case should to be a tutorial aabout limitation or peculiarity of c++ in ARM Compiler v5
P.S. The example with constructor was used because it have smaller code. Method calling the same in case of it callint after construction and not initialised class it's not a reason to calling method this way, because overridding get a possibility to call an overrided method on a begin of new method if it nessesary and at the begin of construction of child class all for parent and child parts is allocated in memory an it filled initial values of calsss fileds.
The clang compiler does not agree with your arguments, sorry.
Please check:
rextester.com/NCWPFL84167
If you want to call the child method (though child is not constructed yer and this is UB), uncomment line "this->vMethod()".
Regards, -- pa
Yes. The code in example executed the same way as in my program.
Maybe I explain not correct.
I think that reason of overriding virtual methods is to call a new emplementation of method even if it calls from parent class method.
Maybe I'm not right.
My aim was to make a basic class and functional in it and override some methods in child with adding functionality.
Your thinking is correct. You just cannot call overridden virtual methods from a constructor / destructor. ( even using this->constructor(); )
Sure again. You once again cannot do that with constructors.
If you actually think about it, you should be able to convince yourself that it cannot work in all cases. (especially ones that require child class initialization)
Of cause correct. May be its not correct from side of standard c++11 I show one example on c# one of most robust oop language. May be its not correct to compare with c++, but its show an essence of the idea.
class Parent { public Parent() { vMethod(); sMethod(); } public virtual void vMethod() { Debug.WriteLine("vParent"); } public void sMethod() { Debug.WriteLine("sParent"); } } class Child : Parent { public Child() { vMethod(); sMethod(); } public override void vMethod() { Debug.WriteLine("vChild"); } public new void sMethod() { Debug.WriteLine("sChild"); } } ... static void Main(string[] args) { Child c = new Child(); ...
The result of program working: vChild sParent vChild sChild
So as we can see, when start constructor of Child class its call Parrent constructor, which calls vMethod() and sMethod(). vMethod() is overriden, so it print "vChild", sMethod is simple class method, so it print "sParent". After Parent constructor calls child constructor code. It again calls vMethod() and sMethod(). vMethod() is overriden, so it again print "vChild". sMethod is declarated as new, so when it calls from Child class, calls new version of sMethod. So it print "sChild".
In this case operators "override" and "virtual" has the meaning. Now its like a "new" operator.
Now in ARM compiler "virtual" operator it like "new" operator in example above, but from the poiny of oop "override" is redefinition of method address in previous position of vertual method table.
When some years ago read how it works, I read that for virtual methods plased table in memory with methods addresses. When you override method in child class in child class table on plase of method putted new address and the old address putten at new plase at the end of virtual method table. So you have a posibility to call old method from parent (for example above
public override void vMethod() { base.vMethod(); Debug.WriteLine("vChild"); }
)
I gust show a code which I try to use an I think you understand an idea. Maybe its more difficult then need for this task, but its beautiful in my opinion
template <class T> class Driver { private: static SemaphoreHandle_t busy_smphr; public: ~Driver<T> (); static T* Open(TickType_t xTicksToWait); virtual void Close(); }; template <class T> SemaphoreHandle_t Driver<T>::busy_smphr = xSemaphoreCreateMutex(); template <class T> Driver<T>::~Driver<T> () { Close(); }; template <class T> T* Driver<T>::Open(TickType_t xTicksToWait) { if (xSemaphoreTake(Driver<T>::busy_smphr, xTicksToWait)==pdTRUE) return new T(); else return NULL; }; template <class T> void Driver<T>::Close() { xSemaphoreGive(T::busy_smphr); };
Ans the child class NewDevice.h
class NewDevice: public Driver<NewDevice> { public: static NewDevice* Open(TickType_t xTicksToWait); static void Init(void); void Method(); virtual void Close(); };
NewDevice.cpp
NewDevice* NewDevice::Open(TickType_t xTicksToWait) { NewDevice* husart = Driver<NewDevice>::Open(xTicksToWait); if (husart!=NULL){ ... } return husart; } void NewDevice::Close() { Driver<NewDevice>::Close(); } void NewDevice::Method() { ... }
And using in code
NewDevice::Init(); NewDevice* drv = NewDevice::Open(10); if (drv!=NULL) drv->Method(); delete drv;
On deleting object calls destructor from parent, which should to call new overriden Close(), which should to call previous Close(). But its doesn't work. I found a slution, but its not so beautiful.
Thanks for your answers.
Calling virtual method from a constructor/destructor is a fundamental C++ programming mistake !
Hank you. I agree with you.
If call virtual method not from constructor all works correct.