Я знаю, что могу сделать:
class Foo;
но могу я вперед объявлять класс как наследовавшийся от другого, как:
class Bar {};
class Foo: public Bar;
Вариант использования в качестве примера был бы ковариантными ссылочными типами возврата.
// somewhere.h
class RA {}
class RB : public RA {}
... и затем в другом заголовке, который не включает somewhere.h
// other.h
class RA;
class A {
public:
virtual RA* Foo(); // this only needs the forward deceleration
}
class RB : public RA; // invalid but...
class B {
public:
virtual RB* Foo(); //
}
Единственная информация компилятор должна должна быть обработать объявление RB* B:Foo()
это RB
имеет RA
как общедоступный базовый класс. Теперь ясно Вам был бы нужен somewhere.h, если Вы намереваетесь сделать какой-либо вид разыменования возвращаемых значений от Foo
. Однако, если некоторые клиенты никогда не звонят Foo
, затем нет никакой причины для них включать somewhere.h, который мог бы значительно ускорить компиляцию.
// wrap it in jQuery, now it's a collection
var $elements = $(someHTML);
// append to the DOM
$("#myDiv").append($elements);
// do stuff, using the initial reference
$elements.effects("highlight", {}, 2000);
-121--633589- Передняя декларация действительно полезна для того, чтобы сообщить компилятору, что класс с таким именем существует и будет объявлен и определен и определен в другом месте. Вы не можете использовать его в любом случае, когда компилятор нуждается в контекстной информации о классе, а также ни одного использования для компилятора, чтобы рассказать это только немного о классе. (Как правило, вы можете использовать передовую декларацию только при обращении к этому классу без другого контекста, например, в качестве параметра или возвращаемого значения.)
Таким образом, вы не можете пересылать декларировать бар в любом сценарии, где вы тогда используете его, чтобы помочь Объявите Foo, и он не имеет смысла иметь передовую декларацию, которая включает в себя базовый класс - что это говорит вам, кроме того?
лучший способ, не позволить пользователям иметь слишком много привилегий. Предоставьте достаточно интерфейса, чтобы пользователи могли делать то, что они хотят. (как банкомат с кнопками только для различных опций, без ввода с клавиатуры). Конечно, если вам нужно, чтобы пользователь нажал на ввод, то предоставьте текстовое поле, а затем в бэкэнд, используйте Perl для обработки запроса (например, санирование и т.д.). Мотив позволить своим пользователям ввести регекс - это искать последовательность узоров верно? В этом случае самый простой и безопасный способ - это сказать им ввести только последовательность. Затем на заднем конце вы используете регекс Perl для его поиска. Есть ли еще какие-либо веские причины для того, чтобы пользователь вводил данные самостоятельно?
-121--2702183-Я бы поместил это в комментарий, но не хватает места.
При написании пользовательского ограничения очень важно проверить параметр roityDirection
и убедиться, что логика выполняется только в нужное время.
Этот параметр указывает, выполняется ли ограничение при обработке входящего запроса или выполняется при создании URL-адреса (например, при вызове Html.ActionLink
).
В вашем случае я думаю, что вы хотите поместить весь ваш соответствующий код в гигантский «if»:
public bool Match(HttpContextBase httpContext, Route route,
string parameterName, RouteValueDictionary values,
RouteDirection routeDirection)
{
if (routeDirection == RouteDirection.IncomingRequest) {
// Only check the content type for incoming requests
return httpContext.Request.ContentType == mimeType;
}
else {
// Always match when generating URLs
return true;
}
}
-121--3643164- Форвардные объявления являются объявлениями, а не определениями. Таким образом, все, что требует объявления класса (как указатели на этот класс), нуждается только в прямом объявлении. Однако все, что требует определения, т.е. должно знать фактическую структуру класса, не будет работать только с форвардным объявлением.
Производные классы определенно должны знать структуру своего родителя, а не только то, что родитель существует, поэтому прямого объявления будет недостаточно.
Не думаю, что это полезно. Подумайте: вы определили класс Bar:
class Bar {
public:
void frob();
};
Теперь вы объявляете класс Foo:
class Foo;
Все, что вы можете сделать с Foo, - это создать указатель на него. Теперь предположим, что вы добавили информацию о том, что Foo
является производным от Bar
:
class Foo: public Bar;
Что теперь вы можете делать, чего не могли делать раньше? Я думаю, что все, что вы можете сделать, это принять указатель на Foo
и преобразовать его в указатель на Bar
, а затем использовать этот указатель.
void frob(Foo* f) {
Bar *b = (Bar)f;
b->frob();
}
Однако вы должны были сгенерировать указатель в другом месте, поэтому вместо этого вы могли просто принять указатель на Bar
.
void frob(Bar* b) {
b->frob();
}