5

Is is possible to create class template in PHP as in C++? PHP probably does not have a similar language structure (like template key words in C++), but maybe there is some clever trick to achieve similar functionality?

I have a Point class that I would like to convert to a template. In class I use typing arguments, therefore, for each class, I would like to pass to the Point method I have to create a new copy of Point class with appropriate types of arguments.

This is sample form C++:

#include<iostream>

template <typename T>
class Point
{
    public:
    T x, y;

    Point(T argX, T argY)
    {
        x = argX;
        y = argY;
    }
};

int main() {
    Point<int> objA(1, 2);
    std::cout << objA.x << ":" << objA.y << std::endl;

    Point<unsigned> objB(3, 4);
    std::cout << objB.x << ":" << objB.y << std::endl;

    return 0;
}

And the same in PHP, but it not work at all (of course the last but one line returns an error):

class SomeClass
{
    public $value;

    public function __construct($value = 0)
    {
        $this->value = $value;
    }
}

class OtherClass
{
    public $value;

    public function __construct($value = 0)
    {
        $this->value = $value;
    }
}

class Point
{
    public $x;
    public $y;

    public function Point(SomeClass $argX, SomeClass $argY)
    {
        $this->x = $argX;
        $this->y = $argY;
    }
}

$objA = new Point(new SomeClass(1), new SomeClass(2));
echo $objA->x->value . ":" . $objA->y->value . PHP_EOL;

$objB = new Point(new OtherClass(3), new OtherClass(4));
echo $objB->x->value . ":" . $objB->y->value . PHP_EOL;
user3106462
  • 189
  • 5
  • 12

1 Answers1

3

The best you can do is PHP's eval-like features, whereby objects can be instantiated like this:

$className = 'SomeClass';
$obj = new $className;

This, combined with the airy-fairy dynamic typing ought to be enough to allow:

$objA = new Point('SomeClass', 1, 2);
echo $objA->x->value . ":" . $objA->y->value . PHP_EOL;

$objB = new Point('OtherClass', 3, 4);
echo $objB->x->value . ":" . $objB->y->value . PHP_EOL;

The requisite definition may look like this:

class Point
{
    public $x;
    public $y;

    public function __construct($className, $argX, $argY)
    {
        $this->x = new $className($argX);
        $this->y = new $className($argY);
    }
}

I'm not sure I'd promote this sort of code style, though. Your original approach seems clearer and cleaner. You can perform a sanity check inside the Point constructor that both arguments share the same type, if you'd like.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • 2
    I would just pass in `$argX` and `$argY` without type - PHP is dynamically typed so there's not much use trying to copy C++ in this respect. If you want you could check in the constructor that the types of the two arguments are the same (i.e. if they are objects then check their classes match) and throw an exception if they are not. – CompuChip Feb 06 '14 at 14:28
  • 1
    @CompuChip: He wants the `$x` and `$y` members to be instantiations of some type, using `$argX` and `$argY` respectively as a constructor argument. I don't see how you can do that without knowing what the type is. Unless he simply uses the code he already started with... – Lightness Races in Orbit Feb 06 '14 at 14:28
  • He wrote `$objA = new Point(new SomeClass(1), new SomeClass(2));` as an example, so passing in instantiated objects. All you have to do is check that they are of the same type. – CompuChip Feb 06 '14 at 14:30
  • @CompuChip: Did you even read the question? You should read the question. Particularly the C++ example that he's trying to mimic. (Note that I've had to reimplement in my PHP example what is an implicit conversion in ctor args in his C++ example) Feel free to write your own contrasting answer, though! – Lightness Races in Orbit Feb 06 '14 at 14:32
  • I read the question, noted that the C++ code correctly represents the way you would do this in C++, and then remarked that C++ and PHP are quite different languages so that the way you would do this in PHP is generally different. Since you originally wrote that "I'm not sure I'd promote this sort of code style" and you have already added the gist of my comment to your answer to provide an alternative, I don't see any need to provide another answer just restating the last line of yours :) I think the point is made and OP should decide for himself, or can ask clarification if he wants. – CompuChip Feb 06 '14 at 14:37