From abaaedfe6b610e6a9cb9d7eff248996347400f93 Mon Sep 17 00:00:00 2001 From: Emiel Bruijntjes Date: Thu, 6 Mar 2014 14:23:06 +0100 Subject: changes to documentation --- documentation/constructors-and-destructors.html | 107 ++++++++++++++++++++---- 1 file changed, 92 insertions(+), 15 deletions(-) diff --git a/documentation/constructors-and-destructors.html b/documentation/constructors-and-destructors.html index f9ec612..e98905c 100644 --- a/documentation/constructors-and-destructors.html +++ b/documentation/constructors-and-destructors.html @@ -1,11 +1,11 @@

Constructors and destructors

- There is a small but important difference between constructor and destructors - in C++, and the __construct() and __destruct() methods in PHP. + There is a small but very important difference between constructor and + destructors in C++, and the __construct() and __destruct() methods in PHP.

A C++ constructor is called on an object that is being initialized, - but that is not in an initialized state yet. You can experience this by + but that is not in an initialized state yet. You can experience this by calling a pure virtual method from a constructor. This will make your program crash, even when the pure virtual method was implemented in the derived class. The reason for this is that inside the C++ constructor the @@ -36,12 +36,13 @@ public: // define a derived class class DERIVED : public BASE { +public: // implementation of the virtual function virtual void doSomething() override { std::cout << "doSomething()" << std::endl; } -} +}; // main procedure int main() @@ -52,17 +53,18 @@ int main()

- The above program crashes. Unlike similar code in PHP. In PHP, when the - __construct() method gets called, the object is already fully initialized - and it is perfectly legal to make calls to abstract methods that are - implemented in derived classes. + The above program crashes (some compilers even refuse to compile this). + Unlike similar code in PHP. In PHP however, when the __construct() method + gets called, the object is already fully initialized and it is perfectly + legal to make calls to abstract methods that are implemented in derived + classes, as you can see in the following example.


-<?php
+<?php
 
-// base class in PHP, we call an abstract method from the constructor
-class BASE 
+// base class in PHP, in which the an abstract method is called
+abstract class BASE 
 {
     // constructor
     public function __construct() 
@@ -90,9 +92,84 @@ $d = new DERIVED();
 ?>    
 

-

+

+ This PHP script correctly outputs 'doSomething()'. This happens because the + __construct() method in PHP is not a real constructor. It constructs nothing, it + has access to all members (that already are constructed), and (when available) + also the base class and overridden methods. In fact, __construct() is a + normal method that just happens to be the very first method that is called right + after the object was constructed, and that is called automatically. +

+

+ This difference is important for you as a C++ programmer, because you should + never confuse your C++ constructor with the __construct() method. In the real + constructor, the C++ object is being constructed while the + PHP object does not yet exist. After the constructor is finished, the PHP + object is created, and the __construct() method gets called. It is therefore + valid to have both a C++ constructor and a __construct() method in your class. +

+

+


+#include <phpcpp.h>
+
+// actual class implementation
+class Counter : public Php::Base
+{
+private:
+    int _value = 0;
+
+public:
+    // c++ constructor
+    Counter() {}
+    
+    // c++ destructor
+    virtual ~Counter() {}
     
-    The __construct() method is thus not part of
-    the object construction process (like the C++ constructor is), but simply is 
-    the first method to be called after the object was fully initialized.
+    // php "constructor"
+    void __construct(Php::Parameters ¶ms)
+    {
+        // copy first parameter (if available)
+        if (params.size() > 0) _value = params[0];
+    }
+
+    // functions to increment and decrement
+    Php::Value increment() { return ++_value; }
+    Php::Value decrement() { return --_value; }
+    Php::Value value() const { return _value; }
+};
+
+extern "C" {
+    PHPCPP_EXPORT void *get_module() {
+        static Php::Extension myExtension("my_extension", "1.0");
+        
+        // description of the class so that PHP knows which methods are accessible
+        Php::Class<Counter> counter("Counter");
+        counter.method("__construct", &Counter::__construct);
+        counter.method("increment", &Counter::increment);
+        counter.method("decrement", &Counter::decrement);
+        counter.method("value", &Counter::value);
+        
+        // add the class to the extension
+        myExtension.add(std::move(counter));
+        
+        // return the extension
+        return myExtension;
+    }
+}
+
+

+

+ The code above shows that __construct() is registered as if it was + a regular method - and that's what it is. The counter example that we've + used before is now extended so that it is possible to give it an initial + value. +

+

+


+<?php
+$counter = new Counter(10);
+$counter->increment();
+echo($counter."\n");
+?>
+

-- cgit v1.2.3