Abstract classes compile error

 

Hi,

I'm using Metatrader 4 build 950.

I am trying to implement an abstract base class use pure virtual methods. After reading the documentation (https://docs.mql4.com/basis/oop/abstract_type), I thought easy - very similar to C++. But is just won't compile - not even the examples in the documentation. The example code in the documentation is as follows:


class CAnimal {
public:
    virtual void       Sound() = 0;   // A pure virtual function
};

//--- Derived from an abstract class
class CCat : public CAnimal {
public:
    virtual void Sound() { Print("Myau"); } // PURE is overridden, CCat is not abstract and can be created
};

The compile spits out these two errors:

  • '=' - semicolon expected  
  • '=' - declaration without type

The only solution I can make works it have empty implementations in the base class.


class CAnimal {
public:
    virtual void Sound() { 
         // Empty implementation.
    }   
};

//--- Derived from an abstract class
class CCat : public CAnimal {
public:
    virtual void Sound() { Print("Myau"); } // PURE is overridden, CCat is not abstract and can be created
};

Not a major problems but the documentation does describe otherwise.

Are pure virtual methods just not supported or have I missed something?


9047.

 
  1. There is no pure in MT4. You must provide a body. I defined a macro:

     * #define PURE(TN)                                   \
     *  {                                                 \
     *     PrintFormat("Pure function call %s[%s@%i]",    \
     *                 __FUNCSIG__, __FILE__, __LINE__);  \
     *     return TN;                                     \
     *  }
     *  ~~~~
     */
    #define PURE(TN) {PrintFormat("Pure function call %s[%s@%i]",__FUNCSIG__,__FILE__,__LINE__);return TN;}
    #define OVERRIDE  // nothing

    and then can write:

    class CAnimal {
    protected:                  // Abstract       
       void   CAnimal(void){}   // Ctor           
    public:                     // Methods        
       void Sound(void) const{ do_sound(); }
    private:                    // Methods        
        virtual void   do_sound() const PURE();   
        virtual string do_other()       PURE("");   
    };
    
    //--- Derived from an abstract class
    class CCat : public CAnimal {
    private:                    // Methods 
        virtual void do_ound() const OVERRIDE{ ...
    };

    It is abstract because you can't call the constructor, only the subclass can.

  2. Virtual methods should always be private, called by non-virtual members. See Virtuality I use the pattern non-virt member, virtual do_member.
 
WHRoeder:
  1. There is no pure in MT4. You must provide a body. I defined a macro:

    and then can write:

    It is abstract because you can't call the constructor, only the subclass can.

  2. Virtual methods should always be private, called by non-virtual members. See Virtuality I use the pattern non-virt member, virtual do_member.

With the protected (private) constructor you still can create a new instance from a class static method. So, it is not a pure abstract class. But it is quite satisfactory workaround for the MT4 purposes I think.

Anyway, not sure what the private virtual function is for.

 
9047:

Hi,

I'm using Metatrader 4 build 950.

This feature is available on beta version only (currently build 961 while connecting on Metaquotes-Demo).
 
Ovo: Anyway, not sure what the private virtual function is for.
  1. See the link provided.
  2. The public calls the private.
  3. The subclass overrides the private.
 
angevoyageur:
This feature is available on beta version only (currently build 961 while connecting on Metaquotes-Demo).
Looks like build 961 has been promoted to live today
 
jamescater:
Looks like build 961 has been promoted to live today

Seeing this topic, I asked Metaquotes explanation...and I got the answer
 
WHRoeder:
  1. See the link provided.
  2. The public calls the private.
  3. The subclass overrides the private.

The common practice with overwriting virtual functions is declaring them as protected, not private. And if this article behind the link claims that such functions have always to be declared as private, then the author is simply wrong. Using protected allows you to avoid reduncancies, using private forces deriving classes to be coded redundant. 
 
WHRoeder:
  1. There is no pure in MT4. You must provide a body. I defined a macro:

    and then can write:

    It is abstract because you can't call the constructor, only the subclass can.

  2. Virtual methods should always be private, called by non-virtual members. See Virtuality I use the pattern non-virt member, virtual do_member.
Thanks for the link, I learned something new today
 
Doerk:
The common practice with overwriting virtual functions is declaring them as protected, not private. And if this article behind the link claims that such functions have always to be declared as private, then the author is simply wrong. Using protected allows you to avoid reduncancies, using private forces deriving classes to be coded redundant. 

The article said :

The point is that virtual functions exist to allow customization; unless they also need to be invoked directly from within derived classes' code, there's no need to ever make them anything but private. But sometimes we do need to invoke the base versions of virtual functions (see the article "Virtually Yours"[5] for an example), and in that case only it makes sense to make those virtual functions protected.

That makes sense.

 
angevoyageur:

The article said :

That makes sense.

I dont think so, because the base class - which is naturally coded upfront and in case of doubts deep in the past - cannot know if any deriving will ever need the basic implemenation of such a virtual function or not. It makes only sense, when its absolutely senseless that the basic implementation could ever be needed, and due to fact that also that cannot be known upfront for all future deriving classes, its rather wrong to declare a virtual function as private as it is right.
Reason: