Questions about OOP - page 4

 
Alain Verleyen #:
The compiler should probably better give a warning about it.

I would also like to see a warning when casting a CBase* pointer to a CDerived* pointer without using dynamic_cast.

Using dynamic_cast means the person knows what they are doing.

 
Alain Verleyen #:
There is no downcast as m_ptr is actually pointing to a CDerived object

I just now realized that by downcast in C++ they mean casting objects, not pointers.

In MQL, only pointers can be cast (if i understand correctly):

https://www.mql5.com/en/docs/basis/types/casting#dynamic_cast

Dynamic typecasting is performed using dynamic_cast operator that can be applied only to pointers to classes.

 
Vladislav Boyko #:

I just now realized that by downcast in C++ they mean casting objects, not pointers.

In MQL, only pointers can be cast (if i understand correctly):

I have no idea why/how you realized that ?

A pointer is a pointer, you can only "cast" what it is pointing to.

In MQL a pointer is not even a pointer (direct memory access) but an handle. And most data can be typecast, more or less reliably.

https://stackoverflow.com/questions/7558837/what-exactly-is-a-type-cast-in-c-c

What exactly is a type cast in C/C++?
What exactly is a type cast in C/C++?
  • 2011.09.26
  • pluckyDuck pluckyDuck 1,139 3 3 gold badges 13 13 silver badges 15 15 bronze badges
  • stackoverflow.com
What exactly is a type cast in C/C++? How does the compiler check if an explicit typecast is needed (and valid)? Does it compare the space required for an value? If I have for example: If I remember correctly a double value requires more space (was it 8 bytes?!) than an integer (4 bytes). And...
 
Alain Verleyen #:
I have no idea why/how you realized that ?

Yes, I said some nonsense here.

Alain Verleyen #:
how

I don't program in c++ and I made a wrong conclusion because I read some material on c++, but I don't have enough basic knowledge to understand it properly.

 
Alain Verleyen #:
A pointer is a pointer, you can only "cast" what it is pointing to.

Thank you very much for your answer. I lack basic knowledge to discuss pointers in c++.

I did some more googling and this is what helped me best understand your statement that I quote:

https://learn.microsoft.com/en-us/cpp/cpp/dynamic-cast-operator?view=msvc-170

A pointer to an object of type  D  can be safely cast to  B  or  C . However, if  D  is cast to point to an  A  object, which instance of  A  would result? This would result in an ambiguous casting error. To get around this problem, you can perform two unambiguous casts. For example:

// dynamic_cast_4.cpp
// compile with: /c /GR
class A {virtual void f();};
class B : public A {virtual void f();};
class C : public A {virtual void f();};
class D : public B, public C {virtual void f();};

void f() {
   D* pd = new D;
   A* pa = dynamic_cast<A*>(pd);   // C4540, ambiguous cast fails at runtime
   B* pb = dynamic_cast<B*>(pd);   // first cast to B
   A* pa2 = dynamic_cast<A*>(pb);   // ok: unambiguous
}

But I don't see any other way to improve my understanding except to learn C++ from the very beginning.

 
Vladislav Boyko #:
I don't program in c++ and I made a wrong conclusion because I read some material on c++, but I don't have enough basic knowledge to understand it properly.

In fact, an approach like this might make sense.

If you periodically feed your brain information that you don't have enough knowledge to understand, then when you start learning it from the very beginning (from simple to complex), the learning process is quite easy.

I think this is due to the fact that information that is not fully understood unconsciously creates an unresolved problem in the head. And when the brain then receives the missing information, it considers it very important and immediately establishes new neural connections without any resistance.

One of O'Reilly's books described quite well how the brain can resist learning new information if it deems it not important enough.

 
Vladislav Boyko #:

Thank you very much for your answer. I lack basic knowledge to discuss pointers in c++.

I did some more googling and this is what helped me best understand your statement that I quote:

But I don't see any other way to improve my understanding except to learn C++ from the very beginning.

What you quote there from C++ is irrelevant for MQL, as it's about multiple inheritance, which is not possible in MQL.

 
Vladislav Boyko #:

In fact, an approach like this might make sense.

If you periodically feed your brain information that you don't have enough knowledge to understand, then when you start learning it from the very beginning (from simple to complex), the learning process is quite easy.

I think this is due to the fact that information that is not fully understood unconsciously creates an unresolved problem in the head. And when the brain then receives the missing information, it considers it very important and immediately establishes new neural connections without any resistance.

One of O'Reilly's books described quite well how the brain can resist learning new information if it deems it not important enough.

That's right. It's sometimes hard to help because your initial problem is unclear. 

You posted a "toy" example about an implicit downcast. But what is the real problem you had ?

You feed the CTest object with a pointer to a CDerived object. Then you stored it in a CBase pointer, but it's still a CDerived object.

A "base" class pointer can store a pointer to a base class object, or to any of the derived classes. m_ptr is of CBase type but it is storing a pointer to CDerived object. When you call getPtr() and store it in a CDerived pointer (ptr) it's all good as m_ptr was ALREADY pointing to a CDerived object. There is no implicit cast. This is just polymorphism.

If instead of a CDerived object, m_ptr was pointing to a CBase object (you would need to change CBase from an abstract class to a instantiable one to do that) :

CTest test(new CBase);

Then m_ptr would store a pointer to a CBase object, and trying to assign that pointer to a CDerived pointer (ptr) would give a runtime error, as an implicit cast can't be done. When you really need to cast a pointer you should use the dynamic_cast operator.

A "derived" class pointer can NOT store a pointer to a base class object. 

A buy (derived) is a trade (base) but a trade is not a buy.

I hope it helps.