diff options
author | Emiel Bruijntjes <emiel.bruijntjes@copernica.com> | 2014-03-12 13:53:48 +0100 |
---|---|---|
committer | Emiel Bruijntjes <emiel.bruijntjes@copernica.com> | 2014-03-12 13:53:48 +0100 |
commit | 8e792d31f499758d3447da46dc85b68356bdbe9b (patch) | |
tree | a0545bae9fc9e6c28cf93e449b896e583483bf7f /documentation | |
parent | f8775b64f67cc464e024cf79cd98eed30c659d25 (diff) |
removed __compare magic method, and added operator< instead
Diffstat (limited to 'documentation')
-rw-r--r-- | documentation/comparing-objects.html | 169 |
1 files changed, 169 insertions, 0 deletions
diff --git a/documentation/comparing-objects.html b/documentation/comparing-objects.html new file mode 100644 index 0000000..f5c57a9 --- /dev/null +++ b/documentation/comparing-objects.html @@ -0,0 +1,169 @@ +<h1>Comparing objects</h1> +<p> + One of the questions we had to ask ourselves when we developed the PHP-CPP + library was whether we should follow PHP conventions or follow C++ + conventions for many of the library features. +</p> +<p> + PHP uses <a href="magic-methods">magic methods</a> and + <a href="magic-interfaces">magic interfaces</a> to add special behavior to + classes. With C++ you can achieve the same, but by using technologies like + operator overloading, implicit constructors and casting operators. The + PHP __invoke() method for example, is more or less identical to operator () + in C++. +</p> +<p> + We have decided to follow the PHP conventions, and use magic methods + and magic interfaces in C++ as well - although we must admit that having + methods that start with two underscores does not make the code very + pretty. But by using magic methods the switch from PHP to C++ is kept simpler + for starting C++ programmers. And on top of that, not all magic methods and + interfaces could have been implemented with core C++ features, so we did have + to use <i>some</i> magic methods and/or interfaces anyway. +</p> +<p> + Besides the magic methods and functions, the Zend engine has additional + features that are not exposed via magic methods, and that only are accessible + for extension programmers. We have already mentioned that PHP-CPP allows you + to implement the __toInteger(), __toFloat() and __toBool() methods (next to + the __toString() that can be implemented in PHP scripts too). Another thing + that is not available in PHP but that can be used by extensions is the + possibility to install a custom object comparison procedure. +</p> +<p> + If you compare two objects in PHP with comparison operators like < ==, != + > (and some others), the Zend engine runs an object comparison function. + The PHP-CPP library interupts this method, and passes the comparison method + to the < operator of your class. In other words, if you want to install + a custom comparison operator, you can do so by implementing operator<. +</p> +<p> +<pre class="language-c++"><code> +#include <phpcpp.h> +/** + * A sample class, that shows how objects can be compared + */ +class MyClass : public Php::Base +{ +private: + /** + * Internal value of the class + * @var int + */ + int _value; + +public: + /** + * C++ constructor + */ + MyClass() + { + // start with random value + _value = rand(); + } + + /** + * C++ destructor + */ + virtual ~MyClass() {} + + /** + * Cast the object to a string + * @return Php::Value + */ + virtual Php::Value __toString() override + { + return std::to_string(_value); + } + + /** + * Comparison operator to compare the object + * @param that + * @return bool + */ + bool operator<(const MyClass &that) const + { + return _value < that._value; + } +}; + +/** + * Switch to C context to ensure that the get_module() function + * is callable by C programs (which the Zend engine is) + */ +extern "C" { + /** + * Startup function that is called by the Zend engine + * to retrieve all information about the extension + * @return void* + */ + PHPCPP_EXPORT void *get_module() { + + // extension object + static Php::Extension myExtension("my_extension", "1.0"); + + // description of the class so that PHP knows + // which methods are accessible + Php::Class<MyClass> myClass("MyClass"); + + // add the class to the extension + myExtension.add(std::move(myClass)); + + // return the extension + return myExtension; + } +} +</code></pre> +</p> +<p> + The comparison function is automatically called when you try to compare + objects in PHP scripts. +</p> +<p> +<pre class="language-php"><code> +<?php +// initialize a couple of objects +$object1 = new MyClass(); +$object2 = new MyClass(); +$object3 = new MyClass(); + +// compare the objects +if ($object1 < $object2) +{ + echo("$object1 is smaller than $object2\n"); +} +else +{ + echo("$object1 is bigger than $object2\n"); +} + +if ($object1 == $object3) +{ + echo("$object1 is equal to $object3\n"); +} +else +{ + echo("$object1 is not equal to $object3\n"); +} +?> +</code></pre> +</p> +<p> + The above PHP script could produce the following output: +</p> +<p> +<pre> +// output +1699622247 is bigger than 151717746 +1699622247 is not equal to 627198306 +</pre> +</p> +<p> + Although we have considered to implement this comparison function as a + magic method (for example __compare), or as a magic interface (for example + Php::Comparable) we have decided to go for the operator< approach that + better fits the C++ language. The big advantage of this choice is that your + objects can now also be used in many C++ STL algorithms, because they use + operator< too. +</p> + |