"PHP" / Говнокод #24811 Ссылка на оригинал

0

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33
  34. 34
  35. 35
  36. 36
  37. 37
  38. 38
  39. 39
  40. 40
  41. 41
  42. 42
  43. 43
  44. 44
/**
 * Cast an object into a different class.
 *
 * Currently this only supports casting DOWN the inheritance chain,
 * that is, an object may only be cast into a class if that class 
 * is a descendant of the object's current class.
 *
 * This is mostly to avoid potentially losing data by casting across
 * incompatable classes.
 *
 * @param object $object The object to cast.
 * @param string $class The class to cast the object into.
 * @return object
 */
function cast($object, $class) {
	if( !is_object($object) ) 
		throw new InvalidArgumentException('$object must be an object.');
	if( !is_string($class) )
		throw new InvalidArgumentException('$class must be a string.');
	if( !class_exists($class) )
		throw new InvalidArgumentException(sprintf('Unknown class: %s.', $class));
	if( !is_subclass_of($class, get_class($object)) ) 
		throw new InvalidArgumentException(sprintf(
			'%s is not a descendant of $object class: %s.',
			$class, get_class($object)
		));
	/**
	 * This is a beautifully ugly hack.
	 *
	 * First, we serialize our object, which turns it into a string, allowing
	 * us to muck about with it using standard string manipulation methods.
	 *
	 * Then, we use preg_replace to change it's defined type to the class
	 * we're casting it to, and then serialize the string back into an
	 * object.
	 */
	return unserialize(
		preg_replace(
			'/^O:\d+:"[^"]++"/', 
			'O:'.strlen($class).':"'.$class.'"',
			serialize($object)
		)
	);
}

Это прекрасно.

Запостил: gost gost, (Updated )

Комментарии (7) RSS

  • Ничего не понимаю. Переведите на "C++".
    Ответить
    • template <typename Base, typename Derived>
      constexpr Base cast(Derived object) {
        static_assert(std::is_base_of<std::decay_t<Base>, std::decay_t<Derived>>(),
                      "Derived is not a descendant of object class: Base.");
        return static_cast<Base>(Derived);
      }


      Конечно можно было б подсуетиться еще с реальными названиями типов Base/Derived: demangle(typeid(T).name()). Но тогда бы уже без constexpr и static_assert. А еще мне лень.
      Ответить
  • Теперь еще пожалуйста напишите функцию для сложения, для вычитания и контейнер типа лист
    Ответить

Добавить комментарий

Помни, guest, за тобой могут следить!

    А не использовать ли нам bbcode?


    8