Экстент jQuery support
объект:
jQuery.support.touch = 'ontouchend' in document;
И теперь вы можете проверить его где угодно, например:
if( jQuery.support.touch )
// do touch stuff
Эту проблему «потери типа» можно решить с помощью шаблонов, но это довольно сложно.
Например.
class Pizza
{
string topping;
public:
virtual double price() const;
};
template <class T, class Base>
class FluentPizza : public Base
{
T* withAnchovies() { ... some implementation ... };
};
class RectPizza : public FluentPizza<RectPizza, Pizza>
{
double price() const { return length*width; :) }
};
class SquarePizza : public FluentPizza<SquarePizza, RectPizza>
{
... something else ...
};
Затем вы можете написать
SquarePizza* p=(new SquarePizza)->withAnchovies();
Шаблон таков, что вместо
class T : public B
вы пишете
class T : public Fluent<T, B>
Другой подход может заключаться в том, чтобы не использовать свободный интерфейс для объектов, а вместо этого использовать указатели:
class Pizza { ... };
class RectPizza { ... };
class SquarePizza { ... whatever you might imagine ... };
template <class T>
class FluentPizzaPtr
{
T* pizza;
public:
FluentPizzaPtr withAnchovies() {
pizza->addAnchovies(); // a nonfluent method
return *this;
}
};
Используйте это так:
FluentPizzaPtr<SquarePizza> squarePizzaFactory() { ... }
FluentPizzaPtr<SquarePizza> myPizza=squarePizzaFactory().withAnchovies();
Одно решение будет работать следующим образом:
return *static_cast<my_type*>(&my_type().with_foo().with_bar());
Использование static_cast
в основном сообщает компилятору: «Я знаю, что делаю здесь».
В C ++ следует сохранять указатели или ссылки, а не значения. Кроме того, вы можете объяснить, что вы подразумеваете под «свободными интерфейсами».
Я бы сделал это на C #, и я считаю, что это будет работать и на C ++, - это предоставить реализацию по умолчанию для with_foo ()
и with_bar ()
... Простите за мой C #, но:
class base {
virtual base with_foo()
{ throw new NotImplementedException(); }
virtual base with_bar();
{ throw new NotImplementedException(); }
}
Вы должны возвращать ссылки / указатели, и вам не нужно хранить информацию о типе.
class base {
public:
base();
virtual ~base();
base &with_foo();
base &with_bar();
protected:
// whatever...
};
class my_type : public base {
public:
my_type();
// more methods...
};
base *build_my_type()
{
return &new my_type()->with_foo().with_bar();
}
У вас уже есть виртуальный деструктор. Предположительно у вас есть другие виртуальные функции. Доступ ко всему осуществляется через базовый тип и объявленные там виртуальные функции.