CrxOop CrxOop: Bringing Object Oriented Programming, and Proper Prototype Based Programming, To Javascript
The aim of the library documented below is to provide developers with a solution to allow development using interfaces and classes as they are known in other object oriented programming (OOP) languages such as C++, C#, Java and PHP. Further more, V1.4 introduces structures, a generalization of the concept of prototypal inheritance, known here as POBP.
Subject
Body*
Email
SUBMIT CLOSE
Menu

1.3 OOP (Classes, Interfaces) Syntax Overview

CrxOop's OOP facility offers one syntax for defining interfaces, two syntaxes for defining classes, and one syntax for everything else. The following is C++ code along with the two different equivalent syntaxes in JS that are provided by CrxOop. Apart from constants, the illustration should cover quickly most of the features supported. The last two tabs are useful for comparing between the C++ code and the JS code.

Figure 01: OOP Syntax Overview
C++
#include <iostream>
using namespace std;
            
class InterfaceA
{
   public: virtual void interfaceAFunction(int pA) = 0;
};
class InterfaceB
{
   public: virtual void interfaceBFunction(int pA) = 0;
};
class InterfaceC : public InterfaceA, public InterfaceB
{
   public: virtual void interfaceCFunction1(int pA) = 0;
   public: virtual void interfaceCFunction2(int pA) = 0;
};
class InterfaceD
{
   public: virtual void interfaceDFunction(int pA) = 0;
};
class classA
{
   friend class classD;
            
   public: classA()
      {cout << "CONSTRUCTING A\n";}
            
   public: char publicVar[19] = "classA::publicVar\n";
   public: int publicVar2 = 5;
   public: int publicVar3[5] = {0, 0, 0, 0, 0};
   public: static char publicStaticVar[25];
   public: static void publicStaticFunction(classA* pClassA)
   {
      cout << "[START]classA::publicStaticFunction()\n";
      classA::privateStaticFunction(5);
      cout << classA::publicStaticVar;
      cout << classA::privateStaticVar;
      cout << pClassA->privateVar;
      cout << "[END]classA::publicStaticFunction()\n";
   }
   public: void publicFunction(int pA)
   {
      cout << "classA::publicFunction()\n";
   }
   public: classA* test(int pA)
   {
      cout << "[START]classA::test()\n";
      this->publicVirtualFunction(5);
      this->privateVirtualFunction(5);
      this->publicPureVirtualFunction(5);
      this->privatePureVirtualFunction(5);
      this->protectedPureVirtualFunction(5);
      this->publicFunction(5);
      this->privateFunction(5);
      classA::privateStaticFunction(5);
      cout << classA::publicStaticVar;
      cout << classA::privateStaticVar;
      cout << "[END]classA::test()\n";
      return this;
   }
   public: virtual void publicVirtualFunction(int pA)
   {
      cout << "classA::publicVirtualFunction()\n";
   }
   public: virtual void publicPureVirtualFunction(int pA) = 0;
            
   private: char privateVar[20] = "classA::privateVar\n";
   private: static char privateStaticVar[26];
   private: static void privateStaticFunction(int pA)
   {
      cout << "classA::privateStaticFunction()\n";
   }
   private: void privateFunction(int pA)
   {
      cout << "classA::privateFunction()\n";
   }
   private: virtual void privateVirtualFunction(int pA)
   {
      cout << "classA::privateVirtualFunction()\n";
   }
   private: virtual void privatePureVirtualFunction(int pA) = 0;
            
   protected: void protectedFunction(int pA)
   {
      cout << "classA::protectedFunction()\n";
   }
   protected: virtual void protectedVirtualFunction(int pA)
   {
      cout << "classA::protectedVirtualFunction()\n";
   }
   protected: virtual void protectedPureVirtualFunction(int pA) = 0;
            
};
char classA::publicStaticVar[25] = "classA::publicStaticVar\n";
char classA::privateStaticVar[26] = "classA::privateStaticVar\n";
class classB: public classA, public InterfaceC, public InterfaceD
{
   public: classB(int pA)
      {cout << "CONSTRUCTING B\n";}
            
   public: char publicVar[19] = "classB::publicVar\n";
            
   public: void publicFunction(int pA)
   {
      cout << "classB::publicFunction()\n";
      if(pA != 1)
         {this->publicFunction(1);}
      this->classA::publicFunction(5);
   }
   public: classB* test(int pA)
   {
      cout << "[START]classB::test()\n";
      this->publicVirtualFunction(5);
      this->publicFunction(5);
      ((classA*)this)->publicFunction(5);
      cout << "[END]classB::test()\n";
      return this;
   }
   public: virtual void publicVirtualFunction(int pA)
   {
      cout << "classB::publicVirtualFunction()\n";
      this->classA::publicVirtualFunction(pA);
   }
   public: virtual void interfaceAFunction(int pA)
      {}
   public: virtual void interfaceBFunction(int pA)
      {}
   public: virtual void interfaceCFunction1(int pA)
      {}
   public: virtual void interfaceCFunction2(int pA)
      {}
   public: virtual void interfaceDFunction(int pA)
      {}
};
class classC: public classB
{
   public: classC():classB(5)
   {
      cout << "CONSTRUCTING C\n";
   }
   public: virtual void publicVirtualFunction(int pA) final
   {
      cout << "classC::publicVirtualFunction()\n";
      this->classA::publicVirtualFunction(pA);
      this->classA::publicFunction(pA);
      this->classA::publicVar2 = 6;
      this->classA::publicVar3[0] = 1;
      cout << this->classA::publicVar3[0] << "\n";
   }
            
   public: virtual void publicPureVirtualFunction(int pA)
   {
      cout << "classC::publicPureVirtualFunction()\n";
   }
   private: virtual void privatePureVirtualFunction(int pA)
   {
      cout << "classC::privatePureVirtualFunction()\n";
   }
   protected: virtual void protectedPureVirtualFunction(int pA)
   {
      cout << "classC::protectedPureVirtualFunction()\n";
   }
};
class classD
{   
   public: void test(classA* pClassA)
   {
      cout << "[START]classD::test()\n";
      cout << pClassA->privateVar;
      pClassA->privatePureVirtualFunction(5);
      pClassA->protectedFunction(5);
      cout << "[END]classD::test()\n";
   }
};
int main()
{
   classC* a = new classC();
   classD* b = new classD();
            
   a->test(5);
   ((classA*)a)->test(5);
   classA::publicStaticFunction((classA*)a);
   b->test((classA*)a);

   return 0;
}
CONSTRUCTING A
CONSTRUCTING B
CONSTRUCTING C
[START]classB::test()
classC::publicVirtualFunction()
classA::publicVirtualFunction()
classA::publicFunction()
1
classB::publicFunction()
classB::publicFunction()
classA::publicFunction()
classA::publicFunction()
classA::publicFunction()
[END]classB::test()
[START]classA::test()
classC::publicVirtualFunction()
classA::publicVirtualFunction()
classA::publicFunction()
1
classA::privateVirtualFunction()
classC::publicPureVirtualFunction()
classC::privatePureVirtualFunction()
classC::protectedPureVirtualFunction()
classA::publicFunction()
classA::privateFunction()
classA::privateStaticFunction()
classA::publicStaticVar
classA::privateStaticVar
[END]classA::test()
[START]classA::publicStaticFunction()
classA::privateStaticFunction()
classA::publicStaticVar
classA::privateStaticVar
classA::privateVar
[END]classA::publicStaticFunction()
[START]classD::test()
classA::privateVar
classC::privatePureVirtualFunction()
classA::protectedFunction()
[END]classD::test()
JS (Tree)
crx_registerInterface("InterfaceA",
{
   "interfaceAFunction": 0
});
crx_registerInterface("InterfaceB",
{
   "interfaceBFunction": 0
});
crx_registerInterface("InterfaceC",
{
   INHERITS: ["InterfaceA", "InterfaceB"],
   "interfaceCFunction1": 0,
   "interfaceCFunction2": 0
});
crx_registerInterface("InterfaceD",
{
   "interfaceDFunction": 0
});
            
crx_registerClass("classA",
{
   FRIENDS: ['classD'],
            
   PUBLIC:
   {
      CONSTRUCT: function()
         {console.log("CONSTRUCTING A");},
      VARS:
      {
         "publicVar": "classA::publicVar",
         "publicVar2": 5,
         "publicVar3": [0, 0, 0, 0, 0]
      },
      STATIC:
      {
         VARS:
         {
            "publicStaticVar": "classA::publicStaticVar"
         },
         FUNCTIONS:
         {
            "publicStaticFunction": function(pClassA)
            {
               console.log("[START]classA::publicStaticFunction()");
               this.STATIC.privateStaticFunction(5);
               console.log(crx_static("classA").publicStaticVar); //OR this.STATIC.publicStaticVar
               console.log(this.STATIC.privateStaticVar);
               console.log(this.O(pClassA).privateVar);
               console.log("[END]classA::publicStaticFunction()");
            }
         }
      },
      FUNCTIONS:
      {
         "publicFunction": function(pA)
         {
            console.log("classA::publicFunction()");
         },
         "test": function(pA)
         {
            console.log("[START]classA::test()");
            this.publicVirtualFunction(5);
            this.privateVirtualFunction(5);
            this.publicPureVirtualFunction(5);
            this.privatePureVirtualFunction(5);
            this.protectedPureVirtualFunction(5);
            this.publicFunction(5);
            this.privateFunction(5);
            this.STATIC.privateStaticFunction(5);
            console.log(crx_static("classA").publicStaticVar);
            console.log(this.STATIC.privateStaticVar);
            console.log("[END]classA::test()");
            return this.THIS;
         }
      },
      VIRTUAL:
      {
         FUNCTIONS:
         {
            "publicVirtualFunction": function(pA)
            {
               console.log("classA::publicVirtualFunction()");
            },
            "publicPureVirtualFunction": 0
            
         }
      }
   },
   PRIVATE:
   {
      VARS:
      {
         "privateVar": "classA::privateVar"
      },
      STATIC:
      {
         VARS:
         {
            "privateStaticVar": "classA::privateStaticVar"
         },
         FUNCTIONS:
         {
            "privateStaticFunction": function(pA)
            {
               console.log("classA::privateStaticFunction()");
            }
         }
      },
      FUNCTIONS:
      {
         "privateFunction":    function(pA)
         {
            console.log("classA::privateFunction()");
         }
      },
      VIRTUAL:
      {
         FUNCTIONS:
         {
            "privateVirtualFunction": function(pA)
            {
               console.log("classA::privateVirtualFunction()");
            },
            "privatePureVirtualFunction": 0
            
         }
      }
   },
   PROTECTED:
   {
      FUNCTIONS:
      {
         "protectedFunction":    function(pA)
         {
            console.log("classA::protectedFunction()");
         }
      },
      VIRTUAL:
      {
         FUNCTIONS:
         {
            "protectedVirtualFunction": function(pA)
            {
               console.log("classA::protectedVirtualFunction()");
            },
            "protectedPureVirtualFunction": 0
            
         }
      }
   }
});
crx_registerClass("classB",
{
   IMPLEMENTS: ["InterfaceC", "InterfaceD"],
   EXTENDS: "classA",
   PUBLIC:
   {
      CONSTRUCT: function(pA)
         {console.log("CONSTRUCTING B");},
      VARS:
      {
         "publicVar": "classB::publicVar"
      },
      FUNCTIONS:
      {
         "publicFunction": function(pA)
         {
            console.log("classB::publicFunction()");
            if(pA != 1)
               {this.publicFunction(1);}
            this.PARENT.publicFunction(5);
         },
         "test": function(pA)
         {
            console.log("[START]classB::test()");
            this.publicVirtualFunction(5);
            this.publicFunction(5);
            this.CAST("classA").publicFunction(5);
            console.log("[END]classB::test()");
            return this.THIS;
         }
      },
      VIRTUAL:
      {
         FUNCTIONS:
         {
            "publicVirtualFunction": function(pA)
            {
               console.log("classB::publicVirtualFunction()");
               this.SR(null, "publicVirtualFunction", pA);
            },
            "interfaceAFunction": function(pA)
               {},
            "interfaceBFunction": function(pA)
               {},
            "interfaceCFunction1": function(pA)
               {},
            "interfaceCFunction2": function(pA)
               {},
            "interfaceDFunction": function(pA)
               {}
         }
      }
   }
});
crx_registerClass("classC",
{
   EXTENDS: "classB",
   PUBLIC:
   {
      CONSTRUCT: function()
      {
         this.PARENT.CONSTRUCT(5);
         console.log("CONSTRUCTING C");
      },
      VIRTUAL:
      {
         FINAL:
         {
            FUNCTIONS:
            {
               "publicVirtualFunction": function(pA)
               {
                  console.log("classC::publicVirtualFunction()");
                  this.SR("classA", "publicVirtualFunction", pA);
                  this.SR("classA", "publicFunction", pA);
                  this.SR("classA", "publicVar2", 6);
                  this.SR("classA", "publicVar3")[0] = 1;
                  console.log(this.SR("classA", "publicVar3")[0]);
               }
            }
         },
         FUNCTIONS:
         {
            "publicPureVirtualFunction": function(pA)
            {
               console.log("classC::publicPureVirtualFunction()\n");
            }
         }
      }
   },
   PRIVATE:
   {
      VIRTUAL:
      {
         FUNCTIONS:
         {
            "privatePureVirtualFunction": function(pA)
            {
               console.log("classC::privatePureVirtualFunction()");
            }
         }
      }
   },
   PROTECTED:
   {
      VIRTUAL:
      {
         FUNCTIONS:
         {
            "protectedPureVirtualFunction": function(pA)
            {
               console.log("classC::protectedPureVirtualFunction()");
            }
         }
      }
   }
});
crx_registerClass('classD',
{   
   PUBLIC:
   {
      FUNCTIONS:
      {
         "test": function(pClassA)
         {
            console.log("[START]classD::test()");
            console.log(this.O(pClassA, "classA").privateVar);
            this.O(pClassA, "classA").privatePureVirtualFunction(5);
            this.O(pClassA, "classA").protectedFunction(5);
            console.log("[END]classD::test()");
         }
      }
   }
});

var a = crx_new("classC");
var b = crx_new("classD");

a.test(5);
a.CAST("classA").test(5);
crx_static("classA").publicStaticFunction(a.CAST("classA"));
b.test(a.CAST("classA"));
CONSTRUCTING B
CONSTRUCTING A
CONSTRUCTING C
[START]classB::test()
classC::publicVirtualFunction()
classA::publicVirtualFunction()
classA::publicFunction()
1
classB::publicFunction()
classB::publicFunction()
classA::publicFunction()
classA::publicFunction()
classA::publicFunction()
[END]classB::test()
[START]classA::test()
classC::publicVirtualFunction()
classA::publicVirtualFunction()
classA::publicFunction()
1
classA::privateVirtualFunction()
classC::publicPureVirtualFunction()
classC::privatePureVirtualFunction()
classC::protectedPureVirtualFunction()
classA::publicFunction()
classA::privateFunction()
classA::privateStaticFunction()
classA::publicStaticVar
classA::privateStaticVar
[END]classA::test()
[START]classA::publicStaticFunction()
classA::privateStaticFunction()
classA::publicStaticVar
classA::privateStaticVar
classA::privateVar
[END]classA::publicStaticFunction()
[START]classD::test()
classA::privateVar
classC::privatePureVirtualFunction()
classA::protectedFunction()
[END]classD::test()
JS (Verbose)
crx_registerInterface("InterfaceA",
{
   "interfaceAFunction": 0
});
crx_registerInterface("InterfaceB",
{
   "interfaceBFunction": 0
});
crx_registerInterface("InterfaceC",
{
   INHERITS: ["InterfaceA", "InterfaceB"],
   "interfaceCFunction1": 0,
   "interfaceCFunction2": 0
});
crx_registerInterface("InterfaceD",
{
   "interfaceDFunction": 0
});
            
crx_registerClass("classA",
{
   "VERBOSE": 1,
   "friends": ["classD"],
            
   "public CONSTRUCT": function()
   {
      console.log("CONSTRUCTING A");
   },
   "public var publicVar": "classA::publicVar",
   "public var publicVar2": 5,
   "public var publicVar3": [0, 0, 0, 0, 0],
   "public static var publicStaticVar": "classA::publicStaticVar",
   "public static function publicStaticFunction": function(pClassA)
   {
      console.log("[START]classA::publicStaticFunction()");
      this.STATIC.privateStaticFunction(5);
      console.log(crx_static("classA").publicStaticVar); //OR this.STATIC.publicStaticVar
      console.log(this.STATIC.privateStaticVar);
      console.log(this.O(pClassA).privateVar);
      console.log("[END]classA::publicStaticFunction()");
   },
   "public function publicFunction": function(pA)
   {
      console.log("classA::publicFunction()");
   },
   "public function test": function(pA)
   {
      console.log("[START]classA::test()");
      this.publicVirtualFunction(5);
      this.privateVirtualFunction(5);
      this.publicPureVirtualFunction(5);
      this.privatePureVirtualFunction(5);
      this.protectedPureVirtualFunction(5);
      this.publicFunction(5);
      this.privateFunction(5);
      this.STATIC.privateStaticFunction(5);
      console.log(this.STATIC.publicStaticVar);
      console.log(this.STATIC.privateStaticVar);
      console.log("[END]classA::test()");
      return this.THIS;
   },
   "public virtual function publicVirtualFunction": function(pA)
   {
      console.log("classA::publicVirtualFunction()");
   },
   "public virtual function publicPureVirtualFunction": 0,
   "private var privateVar": "classA::privateVar",
   "private static var privateStaticVar": "classA::privateStaticVar",
   "private static function privateStaticFunction": function(pA)
   {
      console.log("classA::privateStaticFunction()");
   },
   "private function privateFunction":    function(pA)
   {
      console.log("classA::privateFunction()");
   },
   "private virtual function privateVirtualFunction": function(pA)
   {
      console.log("classA::privateVirtualFunction()");
   },
   "private virtual function privatePureVirtualFunction": 0,
            
   "protected function protectedFunction":    function(pA)
   {
      console.log("classA::protectedFunction()");
   },
   "protected virtual function protectedVirtualFunction": function(pA)
   {
      console.log("classA::protectedVirtualFunction()");
   },
   "protected virtual function protectedPureVirtualFunction": 0
            
});
crx_registerClass("classB",
{
   "VERBOSE": 1,
   "implements": ["InterfaceC", "InterfaceD"],
   "extends": "classA",
   "public CONSTRUCT": function(pA)
   {
      console.log("CONSTRUCTING B");
   },
   "public var publicVar": "classB::publicVar",
   "public function publicFunction": function(pA)
   {
      console.log("classB::publicFunction()");
      if(pA != 1)
         {this.publicFunction(1);}
      this.PARENT.publicFunction(5);
   },
   "public function test": function(pA)
   {
      console.log("[START]classB::test()");
      this.publicVirtualFunction(5);
      this.publicFunction(5);
      this.CAST("classA").publicFunction(5);
      console.log("[END]classB::test()");
      return this.THIS;
   },
   "public virtual function publicVirtualFunction": function(pA)
   {
      console.log("classB::publicVirtualFunction()");
      this.SR(null, "publicVirtualFunction", pA);
   },
   "public virtual function interfaceAFunction": function(pA)
      {},
   "public virtual function interfaceBFunction": function(pA)
      {},
   "public virtual function interfaceCFunction1": function(pA)
      {},
   "public virtual function interfaceCFunction2": function(pA)
      {},
   "public virtual function interfaceDFunction": function(pA)
      {}
});
crx_registerClass("classC",
{
   "VERBOSE": 1,
   "extends": "classB",
   "public CONSTRUCT": function()
   {
      this.PARENT.CONSTRUCT(5);
      console.log("CONSTRUCTING C");
   },
   "public virtual function publicVirtualFunction": function(pA)
   {
      console.log("classC::publicVirtualFunction()");
      this.SR("classA", "publicVirtualFunction", pA);
      this.SR("classA", "publicFunction", pA);
      this.SR("classA", "publicVar2", 6);
      this.SR("classA", "publicVar3")[0] = 1;
      console.log(this.SR("classA", "publicVar3")[0]);
   },
   "public virtual function publicPureVirtualFunction": function(pA)
   {
      console.log("classC::publicPureVirtualFunction()\n");
   },
   "private virtual function privatePureVirtualFunction": function(pA)
   {
      console.log("classC::privatePureVirtualFunction()");
   },
   "protected virtual function protectedPureVirtualFunction": function(pA)
   {
      console.log("classC::protectedPureVirtualFunction()");
   }
});
            
crx_registerClass('classD',
{
   "VERBOSE": 1,
   "public function test": function(pClassA)
   {
      console.log("[START]classD::test()");
      console.log(this.O(pClassA, "classA").privateVar);
      this.O(pClassA, "classA").privatePureVirtualFunction(5);
      this.O(pClassA, "classA").protectedFunction(5);
      console.log("[END]classD::test()");
   }
});
var a = crx_new("classC");
var b = crx_new("classD");
            
a.test(5);
a.CAST("classA").test(5);
crx_static("classA").publicStaticFunction(a.CAST("classA"));
b.test(a.CAST("classA"));
CONSTRUCTING B
CONSTRUCTING A
CONSTRUCTING C
[START]classB::test()
classC::publicVirtualFunction()
classA::publicVirtualFunction()
classA::publicFunction()
1
classB::publicFunction()
classB::publicFunction()
classA::publicFunction()
classA::publicFunction()
classA::publicFunction()
[END]classB::test()
[START]classA::test()
classC::publicVirtualFunction()
classA::publicVirtualFunction()
classA::publicFunction()
1
classA::privateVirtualFunction()
classC::publicPureVirtualFunction()
classC::privatePureVirtualFunction()
classC::protectedPureVirtualFunction()
classA::publicFunction()
classA::privateFunction()
classA::privateStaticFunction()
classA::publicStaticVar
classA::privateStaticVar
[END]classA::test()
[START]classA::publicStaticFunction()
classA::privateStaticFunction()
classA::publicStaticVar
classA::privateStaticVar
classA::privateVar
[END]classA::publicStaticFunction()
[START]classD::test()
classA::privateVar
classC::privatePureVirtualFunction()
classA::protectedFunction()
[END]classD::test()
C++ / JS (Tree)

#include <iostream>
using namespace std;

      

class InterfaceA
{
  public: virtual void interfaceAFunction(int pA) = 0;
};
      

crx_registerInterface("InterfaceA",
{
  "interfaceAFunction": 0
});
      

class InterfaceB
{
  public: virtual void interfaceBFunction(int pA) = 0;
};
      

crx_registerInterface("InterfaceB",
{
  "interfaceBFunction": 0
});
      

class InterfaceC : public InterfaceA, public InterfaceB
{
  public: virtual void interfaceCFunction1(int pA) = 0;
  public: virtual void interfaceCFunction2(int pA) = 0;
};
      

crx_registerInterface("InterfaceC",
{
  INHERITS: ["InterfaceA", "InterfaceB"],
  "interfaceCFunction1": 0,
  "interfaceCFunction2": 0
});
      

class InterfaceD
{
  public: virtual void interfaceDFunction(int pA) = 0;
};
      

crx_registerInterface("InterfaceD",
{
  "interfaceDFunction": 0
});

      

class classA
{
  friend class classD;

      

crx_registerClass("classA",
{
  FRIENDS: ['classD'],

      

  PUBLIC:
  {
      

  public: classA()
    {cout << "CONSTRUCTING A\n";}

      

    CONSTRUCT: function()
      {console.log("CONSTRUCTING A");},
      

  public: char publicVar[19] = "classA::publicVar\n";
  public: int publicVar2 = 5;
  public: int publicVar3[5] = {0, 0, 0, 0, 0};
      

    VARS:
    {
      "publicVar": "classA::publicVar",
      "publicVar2": 5,
      "publicVar3": [0, 0, 0, 0, 0]
    },
      

    STATIC:
    {
      

  public: static char publicStaticVar[25];
      

      VARS:
      {
        "publicStaticVar": "classA::publicStaticVar"
      },
      

  public: static void publicStaticFunction(classA* pClassA)
  {
    cout << "[START]classA::publicStaticFunction()\n";
    classA::privateStaticFunction(5);
    cout << classA::publicStaticVar;
    cout << classA::privateStaticVar;
    cout << pClassA->privateVar;
    cout << "[END]classA::publicStaticFunction()\n";
  }
      

      FUNCTIONS:
      {
        "publicStaticFunction": function(pClassA)
        {
          console.log("[START]classA::publicStaticFunction()");
          this.STATIC.privateStaticFunction(5);
          console.log(crx_static("classA").publicStaticVar); //OR this.STATIC.publicStaticVar
          console.log(this.STATIC.privateStaticVar);
          console.log(this.O(pClassA).privateVar);
          console.log("[END]classA::publicStaticFunction()");
        }
      }
      

    },
    FUNCTIONS:
    {
      

  public: void publicFunction(int pA)
  {
    cout << "classA::publicFunction()\n";
  }
      

      "publicFunction": function(pA)
      {
        console.log("classA::publicFunction()");
      },
      

  public: classA* test(int pA)
  {
    cout << "[START]classA::test()\n";
    this->publicVirtualFunction(5);
    this->privateVirtualFunction(5);
    this->publicPureVirtualFunction(5);
    this->privatePureVirtualFunction(5);
    this->protectedPureVirtualFunction(5);
    this->publicFunction(5);
    this->privateFunction(5);
    classA::privateStaticFunction(5);
    cout << classA::publicStaticVar;
    cout << classA::privateStaticVar;
    cout << "[END]classA::test()\n";

    return this;
  }
      

      "test": function(pA)
      {
        console.log("[START]classA::test()");
        this.publicVirtualFunction(5);
        this.privateVirtualFunction(5);
        this.publicPureVirtualFunction(5);
        this.privatePureVirtualFunction(5);
        this.protectedPureVirtualFunction(5);
        this.publicFunction(5);
        this.privateFunction(5);
        this.STATIC.privateStaticFunction(5);
        console.log(crx_static("classA").publicStaticVar);
        console.log(this.STATIC.privateStaticVar);
        console.log("[END]classA::test()");

        return this.THIS;
      }
      

    },
    VIRTUAL:
    {
      FUNCTIONS:
      {
      

  public: virtual void publicVirtualFunction(int pA)
  {
    cout << "classA::publicVirtualFunction()\n";
  }
      

        "publicVirtualFunction": function(pA)
        {
          console.log("classA::publicVirtualFunction()");
        },
      

  public: virtual void publicPureVirtualFunction(int pA) = 0;

      

        "publicPureVirtualFunction": 0

      

      }
    }
  },
  PRIVATE:
  {
      

  private: char privateVar[20] = "classA::privateVar\n";
      

    VARS:
    {
      "privateVar": "classA::privateVar"
    },
      

    STATIC:
    {
      

  private: static char privateStaticVar[26];
      

      VARS:
      {
        "privateStaticVar": "classA::privateStaticVar"
      },
      

  private: static void privateStaticFunction(int pA)
  {
    cout << "classA::privateStaticFunction()\n";
  }
      

      FUNCTIONS:
      {
        "privateStaticFunction": function(pA)
        {
          console.log("classA::privateStaticFunction()");
        }
      }
      

    },
      

  private: void privateFunction(int pA)
  {
    cout << "classA::privateFunction()\n";
  }
      

    FUNCTIONS:
    {
      "privateFunction":   function(pA)
      {
        console.log("classA::privateFunction()");
      }
    },
      

    VIRTUAL:
    {
      FUNCTIONS:
      {
      

  private: virtual void privateVirtualFunction(int pA)
  {
    cout << "classA::privateVirtualFunction()\n";
  }
      

        "privateVirtualFunction": function(pA)
        {
          console.log("classA::privateVirtualFunction()");
        },
      

  private: virtual void privatePureVirtualFunction(int pA) = 0;

      

        "privatePureVirtualFunction": 0

      

      }
    }
  },
  PROTECTED:
  {
      

  protected: void protectedFunction(int pA)
  {
    cout << "classA::protectedFunction()\n";
  }
      

    FUNCTIONS:
    {
      "protectedFunction":   function(pA)
      {
        console.log("classA::protectedFunction()");
      }
    },
      

    VIRTUAL:
    {
      FUNCTIONS:
      {
      

  protected: virtual void protectedVirtualFunction(int pA)
  {
    cout << "classA::protectedVirtualFunction()\n";
  }
      

        "protectedVirtualFunction": function(pA)
        {
          console.log("classA::protectedVirtualFunction()");
        },
      

  protected: virtual void protectedPureVirtualFunction(int pA) = 0;

      

        "protectedPureVirtualFunction": 0

      

};
      

      }
    }
  }
});
      

char classA::publicStaticVar[25] = "classA::publicStaticVar\n";
char classA::privateStaticVar[26] = "classA::privateStaticVar\n";
      

class classB: public classA, public InterfaceC, public InterfaceD
{
      

crx_registerClass("classB",
{
  IMPLEMENTS: ["InterfaceC", "InterfaceD"],
  EXTENDS: "classA",
      

  PUBLIC:
  {
      

  public: classB(int pA)
    {cout << "CONSTRUCTING B\n";}

      

    CONSTRUCT: function(pA)
      {console.log("CONSTRUCTING B");},
      

  public: char publicVar[19] = "classB::publicVar\n";

      

    VARS:
    {
      "publicVar": "classB::publicVar"
    },
      

    FUNCTIONS:
    {
      

  public: void publicFunction(int pA)
  {
    cout << "classB::publicFunction()\n";

    if(pA != 1)
      {this->publicFunction(1);}

    this->classA::publicFunction(5);
  }
      

      "publicFunction": function(pA)
      {
        console.log("classB::publicFunction()");

        if(pA != 1)
          {this.publicFunction(1);}

        this.PARENT.publicFunction(5);
      },
      

  public: classB* test(int pA)
  {
    cout << "[START]classB::test()\n";
    this->publicVirtualFunction(5);
    this->publicFunction(5);
    ((classA*)this)->publicFunction(5);
    cout << "[END]classB::test()\n";

    return this;
  }
      

      "test": function(pA)
      {
        console.log("[START]classB::test()");
        this.publicVirtualFunction(5);
        this.publicFunction(5);
        this.CAST("classA").publicFunction(5);
        console.log("[END]classB::test()");

        return this.THIS;
      }
      

    },
      

  public: virtual void publicVirtualFunction(int pA)
  {
    cout << "classB::publicVirtualFunction()\n";

    this->classA::publicVirtualFunction(pA);
  }
  public: virtual void interfaceAFunction(int pA)
    {}
  public: virtual void interfaceBFunction(int pA)
    {}
  public: virtual void interfaceCFunction1(int pA)
    {}
  public: virtual void interfaceCFunction2(int pA)
    {}
  public: virtual void interfaceDFunction(int pA)
    {}
      

    VIRTUAL:
    {
      FUNCTIONS:
      {
        "publicVirtualFunction": function(pA)
        {
          console.log("classB::publicVirtualFunction()");
          this.SR(null, "publicVirtualFunction", pA);
        },
        "interfaceAFunction": function(pA)
          {},
        "interfaceBFunction": function(pA)
          {},
        "interfaceCFunction1": function(pA)
          {},
        "interfaceCFunction2": function(pA)
          {},
        "interfaceDFunction": function(pA)
          {}
      }
    }
      

};
      

  }
});
      

class classC: public classB
{
      

crx_registerClass("classC",
{
  EXTENDS: "classB",
      

  PUBLIC:
  {
      

  public: classC():classB(5)
  {
    cout << "CONSTRUCTING C\n";
  }
      

    CONSTRUCT: function()
    {
      this.PARENT.CONSTRUCT(5);
      console.log("CONSTRUCTING C");
    },
      

    VIRTUAL:
    {
      

  public: virtual void publicVirtualFunction(int pA) final
  {
    cout << "classC::publicVirtualFunction()\n";

    this->classA::publicVirtualFunction(pA);
    this->classA::publicFunction(pA);
    this->classA::publicVar2 = 6;
    this->classA::publicVar3[0] = 1;
    cout << this->classA::publicVar3[0] << "\n";
  }

      

      FINAL:
      {
        FUNCTIONS:
        {
          "publicVirtualFunction": function(pA)
          {
            console.log("classC::publicVirtualFunction()");

            this.SR("classA", "publicVirtualFunction", pA);
            this.SR("classA", "publicFunction", pA);
            this.SR("classA", "publicVar2", 6);
            this.SR("classA", "publicVar3")[0] = 1;
            console.log(this.SR("classA", "publicVar3")[0]);
          }
        }
      },
      

  public: virtual void publicPureVirtualFunction(int pA)
  {
    cout << "classC::publicPureVirtualFunction()\n";
  }
      

      FUNCTIONS:
      {
        "publicPureVirtualFunction": function(pA)
        {
          console.log("classC::publicPureVirtualFunction()\n");
        }
      }
      

    }
  },
      

  private: virtual void privatePureVirtualFunction(int pA)
  {
    cout << "classC::privatePureVirtualFunction()\n";
  }
      

  PRIVATE:
  {
    VIRTUAL:
    {
      FUNCTIONS:
      {
        "privatePureVirtualFunction": function(pA)
        {
          console.log("classC::privatePureVirtualFunction()");
        }
      }
    }
  },
      

  protected: virtual void protectedPureVirtualFunction(int pA)
  {
    cout << "classC::protectedPureVirtualFunction()\n";
  }
      

  PROTECTED:
  {
    VIRTUAL:
    {
      FUNCTIONS:
      {
        "protectedPureVirtualFunction": function(pA)
        {
          console.log("classC::protectedPureVirtualFunction()");
        }
      }
    }
  }
      

};
      

});
      

class classD
{  
  public: void test(classA* pClassA)
  {
    cout << "[START]classD::test()\n";
    cout << pClassA->privateVar;
    pClassA->privatePureVirtualFunction(5);
    pClassA->protectedFunction(5);
    cout << "[END]classD::test()\n";
  }
};
      

crx_registerClass('classD',
{  
  PUBLIC:
  {
    FUNCTIONS:
    {
      "test": function(pClassA)
      {
        console.log("[START]classD::test()");
        console.log(this.O(pClassA, "classA").privateVar);
        this.O(pClassA, "classA").privatePureVirtualFunction(5);
        this.O(pClassA, "classA").protectedFunction(5);
        console.log("[END]classD::test()");
      }
    }
  }
});
      

int main()
{
      

  classC* a = new classC();
  classD* b = new classD();

      


var a = crx_new("classC");
var b = crx_new("classD");
      

  a->test(5);
  ((classA*)a)->test(5);
  classA::publicStaticFunction((classA*)a);
  b->test((classA*)a);
      


a.test(5);
a.CAST("classA").test(5);
crx_static("classA").publicStaticFunction(a.CAST("classA"));
b.test(a.CAST("classA"));
      


  return 0;
}
      
CONSTRUCTING A
CONSTRUCTING B
CONSTRUCTING C
[START]classB::test()
classC::publicVirtualFunction()
classA::publicVirtualFunction()
classA::publicFunction()
1
classB::publicFunction()
classB::publicFunction()
classA::publicFunction()
classA::publicFunction()
classA::publicFunction()
[END]classB::test()
[START]classA::test()
classC::publicVirtualFunction()
classA::publicVirtualFunction()
classA::publicFunction()
1
classA::privateVirtualFunction()
classC::publicPureVirtualFunction()
classC::privatePureVirtualFunction()
classC::protectedPureVirtualFunction()
classA::publicFunction()
classA::privateFunction()
classA::privateStaticFunction()
classA::publicStaticVar
classA::privateStaticVar
[END]classA::test()
[START]classA::publicStaticFunction()
classA::privateStaticFunction()
classA::publicStaticVar
classA::privateStaticVar
classA::privateVar
[END]classA::publicStaticFunction()
[START]classD::test()
classA::privateVar
classC::privatePureVirtualFunction()
classA::protectedFunction()
[END]classD::test()
CONSTRUCTING B
CONSTRUCTING A
CONSTRUCTING C
[START]classB::test()
classC::publicVirtualFunction()
classA::publicVirtualFunction()
classA::publicFunction()
1
classB::publicFunction()
classB::publicFunction()
classA::publicFunction()
classA::publicFunction()
classA::publicFunction()
[END]classB::test()
[START]classA::test()
classC::publicVirtualFunction()
classA::publicVirtualFunction()
classA::publicFunction()
1
classA::privateVirtualFunction()
classC::publicPureVirtualFunction()
classC::privatePureVirtualFunction()
classC::protectedPureVirtualFunction()
classA::publicFunction()
classA::privateFunction()
classA::privateStaticFunction()
classA::publicStaticVar
classA::privateStaticVar
[END]classA::test()
[START]classA::publicStaticFunction()
classA::privateStaticFunction()
classA::publicStaticVar
classA::privateStaticVar
classA::privateVar
[END]classA::publicStaticFunction()
[START]classD::test()
classA::privateVar
classC::privatePureVirtualFunction()
classA::protectedFunction()
[END]classD::test()
C++ / JS (Verbose)

#include <iostream>
using namespace std;

      

class InterfaceA
{
  public: virtual void interfaceAFunction(int pA) = 0;
};
      

crx_registerInterface("InterfaceA",
{
  "interfaceAFunction": 0
});
      

class InterfaceB
{
  public: virtual void interfaceBFunction(int pA) = 0;
};
      

crx_registerInterface("InterfaceB",
{
  "interfaceBFunction": 0
});
      

class InterfaceC : public InterfaceA, public InterfaceB
{
  public: virtual void interfaceCFunction1(int pA) = 0;
  public: virtual void interfaceCFunction2(int pA) = 0;
};
      

crx_registerInterface("InterfaceC",
{
  INHERITS: ["InterfaceA", "InterfaceB"],
  "interfaceCFunction1": 0,
  "interfaceCFunction2": 0
});
      

class InterfaceD
{
  public: virtual void interfaceDFunction(int pA) = 0;
};
      

crx_registerInterface("InterfaceD",
{
  "interfaceDFunction": 0
});

      

class classA
{
  friend class classD;

      

crx_registerClass("classA",
{
  "VERBOSE": 1,
  "friends": ["classD"],

      

  public: classA()
    {cout << "CONSTRUCTING A\n";}

      

  "public CONSTRUCT": function()
  {
    console.log("CONSTRUCTING A");
  },
      

  public: char publicVar[19] = "classA::publicVar\n";
  public: int publicVar2 = 5;
  public: int publicVar3[5] = {0, 0, 0, 0, 0};
      

  "public var publicVar": "classA::publicVar",
  "public var publicVar2": 5,
  "public var publicVar3": [0, 0, 0, 0, 0],
      

  public: static char publicStaticVar[25];
      

  "public static var publicStaticVar": "classA::publicStaticVar",
      

  public: static void publicStaticFunction(classA* pClassA)
  {
    cout << "[START]classA::publicStaticFunction()\n";
    classA::privateStaticFunction(5);
    cout << classA::publicStaticVar;
    cout << classA::privateStaticVar;
    cout << pClassA->privateVar;
    cout << "[END]classA::publicStaticFunction()\n";
  }
      

  "public static function publicStaticFunction": function(pClassA)
  {
    console.log("[START]classA::publicStaticFunction()");
    this.STATIC.privateStaticFunction(5);
    console.log(crx_static("classA").publicStaticVar); //OR this.STATIC.publicStaticVar
    console.log(this.STATIC.privateStaticVar);
    console.log(this.O(pClassA).privateVar);
    console.log("[END]classA::publicStaticFunction()");
  },
      

  public: void publicFunction(int pA)
  {
    cout << "classA::publicFunction()\n";
  }
      

  "public function publicFunction": function(pA)
  {
    console.log("classA::publicFunction()");
  },
      

  public: classA* test(int pA)
  {
    cout << "[START]classA::test()\n";
    this->publicVirtualFunction(5);
    this->privateVirtualFunction(5);
    this->publicPureVirtualFunction(5);
    this->privatePureVirtualFunction(5);
    this->protectedPureVirtualFunction(5);
    this->publicFunction(5);
    this->privateFunction(5);
    classA::privateStaticFunction(5);
    cout << classA::publicStaticVar;
    cout << classA::privateStaticVar;
    cout << "[END]classA::test()\n";

    return this;
  }
      

  "public function test": function(pA)
  {
    console.log("[START]classA::test()");
    this.publicVirtualFunction(5);
    this.privateVirtualFunction(5);
    this.publicPureVirtualFunction(5);
    this.privatePureVirtualFunction(5);
    this.protectedPureVirtualFunction(5);
    this.publicFunction(5);
    this.privateFunction(5);
    this.STATIC.privateStaticFunction(5);
    console.log(this.STATIC.publicStaticVar);
    console.log(this.STATIC.privateStaticVar);
    console.log("[END]classA::test()");

    return this.THIS;
  },
      

  public: virtual void publicVirtualFunction(int pA)
  {
    cout << "classA::publicVirtualFunction()\n";
  }
      

  "public virtual function publicVirtualFunction": function(pA)
  {
    console.log("classA::publicVirtualFunction()");
  },
      

  public: virtual void publicPureVirtualFunction(int pA) = 0;

      

  "public virtual function publicPureVirtualFunction": 0,
      

  private: char privateVar[20] = "classA::privateVar\n";
      

  "private var privateVar": "classA::privateVar",
      

  private: static char privateStaticVar[26];
      

  "private static var privateStaticVar": "classA::privateStaticVar",
      

  private: static void privateStaticFunction(int pA)
  {
    cout << "classA::privateStaticFunction()\n";
  }
      

  "private static function privateStaticFunction": function(pA)
  {
    console.log("classA::privateStaticFunction()");
  },
      

  private: void privateFunction(int pA)
  {
    cout << "classA::privateFunction()\n";
  }
      

  "private function privateFunction":   function(pA)
  {
    console.log("classA::privateFunction()");
  },
      

  private: virtual void privateVirtualFunction(int pA)
  {
    cout << "classA::privateVirtualFunction()\n";
  }
      

  "private virtual function privateVirtualFunction": function(pA)
  {
    console.log("classA::privateVirtualFunction()");
  },
      

  private: virtual void privatePureVirtualFunction(int pA) = 0;

      

  "private virtual function privatePureVirtualFunction": 0,

      

  protected: void protectedFunction(int pA)
  {
    cout << "classA::protectedFunction()\n";
  }
      

  "protected function protectedFunction":   function(pA)
  {
    console.log("classA::protectedFunction()");
  },
      

  protected: virtual void protectedVirtualFunction(int pA)
  {
    cout << "classA::protectedVirtualFunction()\n";
  }
      

  "protected virtual function protectedVirtualFunction": function(pA)
  {
    console.log("classA::protectedVirtualFunction()");
  },
      

  protected: virtual void protectedPureVirtualFunction(int pA) = 0;

      

  "protected virtual function protectedPureVirtualFunction": 0

      

};
      

});
      

char classA::publicStaticVar[25] = "classA::publicStaticVar\n";
char classA::privateStaticVar[26] = "classA::privateStaticVar\n";
      

class classB: public classA, public InterfaceC, public InterfaceD
{
      

crx_registerClass("classB",
{
  "VERBOSE": 1,
  "implements": ["InterfaceC", "InterfaceD"],
  "extends": "classA",
      

  public: classB(int pA)
    {cout << "CONSTRUCTING B\n";}

      

  "public CONSTRUCT": function(pA)
  {
    console.log("CONSTRUCTING B");
  },
      

  public: char publicVar[19] = "classB::publicVar\n";

      

  "public var publicVar": "classB::publicVar",
      

  public: void publicFunction(int pA)
  {
    cout << "classB::publicFunction()\n";

    if(pA != 1)
      {this->publicFunction(1);}

    this->classA::publicFunction(5);
  }
      

  "public function publicFunction": function(pA)
  {
    console.log("classB::publicFunction()");

    if(pA != 1)
      {this.publicFunction(1);}

    this.PARENT.publicFunction(5);
  },
      

  public: classB* test(int pA)
  {
    cout << "[START]classB::test()\n";
    this->publicVirtualFunction(5);
    this->publicFunction(5);
    ((classA*)this)->publicFunction(5);
    cout << "[END]classB::test()\n";

    return this;
  }
      

  "public function test": function(pA)
  {
    console.log("[START]classB::test()");
    this.publicVirtualFunction(5);
    this.publicFunction(5);
    this.CAST("classA").publicFunction(5);
    console.log("[END]classB::test()");

    return this.THIS;
  },
      

  public: virtual void publicVirtualFunction(int pA)
  {
    cout << "classB::publicVirtualFunction()\n";

    this->classA::publicVirtualFunction(pA);
  }
  public: virtual void interfaceAFunction(int pA)
    {}
  public: virtual void interfaceBFunction(int pA)
    {}
  public: virtual void interfaceCFunction1(int pA)
    {}
  public: virtual void interfaceCFunction2(int pA)
    {}
  public: virtual void interfaceDFunction(int pA)
    {}
      

  "public virtual function publicVirtualFunction": function(pA)
  {
    console.log("classB::publicVirtualFunction()");
    this.SR(null, "publicVirtualFunction", pA);
  },
  "public virtual function interfaceAFunction": function(pA)
    {},
  "public virtual function interfaceBFunction": function(pA)
    {},
  "public virtual function interfaceCFunction1": function(pA)
    {},
  "public virtual function interfaceCFunction2": function(pA)
    {},
  "public virtual function interfaceDFunction": function(pA)
    {}
      

};
      

});
      

class classC: public classB
{
      

crx_registerClass("classC",
{
  "VERBOSE": 1,
  "extends": "classB",
      

  public: classC():classB(5)
  {
    cout << "CONSTRUCTING C\n";
  }
      

  "public CONSTRUCT": function()
  {
    this.PARENT.CONSTRUCT(5);
    console.log("CONSTRUCTING C");
  },
      

  public: virtual void publicVirtualFunction(int pA) final
  {
    cout << "classC::publicVirtualFunction()\n";

    this->classA::publicVirtualFunction(pA);
    this->classA::publicFunction(pA);
    this->classA::publicVar2 = 6;
    this->classA::publicVar3[0] = 1;
    cout << this->classA::publicVar3[0] << "\n";
  }

      

  "public virtual function publicVirtualFunction": function(pA)
  {
    console.log("classC::publicVirtualFunction()");

    this.SR("classA", "publicVirtualFunction", pA);
    this.SR("classA", "publicFunction", pA);
    this.SR("classA", "publicVar2", 6);
    this.SR("classA", "publicVar3")[0] = 1;
    console.log(this.SR("classA", "publicVar3")[0]);
  },
      

  public: virtual void publicPureVirtualFunction(int pA)
  {
    cout << "classC::publicPureVirtualFunction()\n";
  }
      

  "public virtual function publicPureVirtualFunction": function(pA)
  {
    console.log("classC::publicPureVirtualFunction()\n");
  },
      

  private: virtual void privatePureVirtualFunction(int pA)
  {
    cout << "classC::privatePureVirtualFunction()\n";
  }
      

  "private virtual function privatePureVirtualFunction": function(pA)
  {
    console.log("classC::privatePureVirtualFunction()");
  },
      

  protected: virtual void protectedPureVirtualFunction(int pA)
  {
    cout << "classC::protectedPureVirtualFunction()\n";
  }
      

  "protected virtual function protectedPureVirtualFunction": function(pA)
  {
    console.log("classC::protectedPureVirtualFunction()");
  }
      

};
      

});

      

class classD
{  
  public: void test(classA* pClassA)
  {
    cout << "[START]classD::test()\n";
    cout << pClassA->privateVar;
    pClassA->privatePureVirtualFunction(5);
    pClassA->protectedFunction(5);
    cout << "[END]classD::test()\n";
  }
};
      

crx_registerClass('classD',
{
  "VERBOSE": 1,
  "public function test": function(pClassA)
  {
    console.log("[START]classD::test()");
    console.log(this.O(pClassA, "classA").privateVar);
    this.O(pClassA, "classA").privatePureVirtualFunction(5);
    this.O(pClassA, "classA").protectedFunction(5);
    console.log("[END]classD::test()");
  }
});
      

int main()
{
      

  classC* a = new classC();
  classD* b = new classD();

      

var a = crx_new("classC");
var b = crx_new("classD");

      

  a->test(5);
  ((classA*)a)->test(5);
  classA::publicStaticFunction((classA*)a);
  b->test((classA*)a);
      

a.test(5);
a.CAST("classA").test(5);
crx_static("classA").publicStaticFunction(a.CAST("classA"));
b.test(a.CAST("classA"));
      


  return 0;
}
      
CONSTRUCTING A
CONSTRUCTING B
CONSTRUCTING C
[START]classB::test()
classC::publicVirtualFunction()
classA::publicVirtualFunction()
classA::publicFunction()
1
classB::publicFunction()
classB::publicFunction()
classA::publicFunction()
classA::publicFunction()
classA::publicFunction()
[END]classB::test()
[START]classA::test()
classC::publicVirtualFunction()
classA::publicVirtualFunction()
classA::publicFunction()
1
classA::privateVirtualFunction()
classC::publicPureVirtualFunction()
classC::privatePureVirtualFunction()
classC::protectedPureVirtualFunction()
classA::publicFunction()
classA::privateFunction()
classA::privateStaticFunction()
classA::publicStaticVar
classA::privateStaticVar
[END]classA::test()
[START]classA::publicStaticFunction()
classA::privateStaticFunction()
classA::publicStaticVar
classA::privateStaticVar
classA::privateVar
[END]classA::publicStaticFunction()
[START]classD::test()
classA::privateVar
classC::privatePureVirtualFunction()
classA::protectedFunction()
[END]classD::test()
CONSTRUCTING B
CONSTRUCTING A
CONSTRUCTING C
[START]classB::test()
classC::publicVirtualFunction()
classA::publicVirtualFunction()
classA::publicFunction()
1
classB::publicFunction()
classB::publicFunction()
classA::publicFunction()
classA::publicFunction()
classA::publicFunction()
[END]classB::test()
[START]classA::test()
classC::publicVirtualFunction()
classA::publicVirtualFunction()
classA::publicFunction()
1
classA::privateVirtualFunction()
classC::publicPureVirtualFunction()
classC::privatePureVirtualFunction()
classC::protectedPureVirtualFunction()
classA::publicFunction()
classA::privateFunction()
classA::privateStaticFunction()
classA::publicStaticVar
classA::privateStaticVar
[END]classA::test()
[START]classA::publicStaticFunction()
classA::privateStaticFunction()
classA::publicStaticVar
classA::privateStaticVar
classA::privateVar
[END]classA::publicStaticFunction()
[START]classD::test()
classA::privateVar
classC::privatePureVirtualFunction()
classA::protectedFunction()
[END]classD::test()

1.3.1 Tree Syntax

Look at Figure 1, the Tree Syntax tab. There are Few things to note:

1.3.2 Verbose Syntax

Look at Figure 1, the Verbose Syntax tab. There are Few things to note:

1.3.3 Keywords

Refer back to Figure 1. CrxOop provides a number of 'keywords' to provide its functionality, most of which appear in the JS code in the figure, and can be understood by comparing the JS code to that of C++. The 'keywords' fall under three types:

  • Definition Keywords: These keywords are available in class definitions and interface definitions. In the tree syntax, they are object property names, and are case sensitive. In the verbose syntax they are part of object property names and are case insensitive apart for "VERBOSE" and "CONSTRUCT". Also note that in the verbose syntax, VARS becomes VAR, and FUNCTIONS becomes FUNCTION. Further more, but not shown in Figure 1, "CONSTS" becomes "CONST".

    The following is the list of these keywords: VERBOSE, FRIENDS, IMPLEMENTS, EXTENDS, PUBLIC, PROTECTED, PRIVATE, CONSTRUCT, VARS, FUNCTIONS, STATIC, and CONSTS.

  • Class Keywords: These keywords are used in the class instance functions, whether public, protected, private, public virtual, protected virtual, or private virtual. They are property names of actual variables and functions placed on the object pointed to by the javascript keyword "this" in the instance function. Hence they are case sensitive. These keywords, along with the native "this", which is found in both instance and class functions, and apart from "THIS", and "PARENT", must never be passed around as function parameters and function returns when accessed using "this". This rule also applies to the return of "O"(), i.e. the value returned by this.O().

    The following is the list of these keywords: O, THIS, PARENT, CONSTRUCT, SR, STATIC, CAST, and ANNUL.

    Needless to say, class keywords are not found in static functions, except for this, "STATIC" and "O".

  • Global Keywords: In the browser, these keywords are global javascript functions that can be used any where, and hence they are case sensitive. In Node.js, this may or may not be the case. Please refer to the section on Node.js usage.

    The following is the list of these keywords: crx_registerClass(), crx_registerInterface, crx_new and crx_static.

Keep in mind that all keywords, and typing functions which will be discussed later and are provided by CrxOop, can lead to fatal errors if used incorrectly. In other words, treat them all as actual keywords, the same way you do with native keywords in C++ and other languages. In other languages a misused keyword will either mean compilation failure, or runtime halt if the language is interpreted.

1.3.4 Summary Of Supported Features

The following is a list of the high level features supported in CrxOop, which are usually seen in C++ and other OOP languages: