2013-02-27 7 views
-2

В C# можно определить следующим образом:Generic переменная класса определенного типа

public interface BaseObject 
{ 
    int GetValue(); 
} 

public class Test<T> where T : BaseClass 
{ 
    T BaseObject; 
} 

, который означает, что я знаю, что я могу назвать alwaysa BaseObject.GetValue()/BaseObject-> GetValue(); потому что я знаю, что базовый объект имеет этот метод.

Есть ли аналогичный способ сделать это на C++? Чтобы я мог определить интерфейс, который могут наследовать несколько классов, и класс, который может воспользоваться этим.

ответ

-1

Шаблоны, которые являются еще более мощными, чем C# generics (не говоря уже о том, что они обязательно лучше, просто разные).

template<class T> 
class foo 
{ 
public: 
    int whatever() 
    { 
     return obj.GetValue(); 
    } 
private: 
    T obj; 
}; 

Для каждого аргумента шаблона создается отдельный класс. Если вы укажете тип шаблона, который приведет к ошибке, которую вы узнаете во время компиляции.

+0

Но мне нужно ограничить Т определенным типом. Таким образом, он должен быть объектом, который наследуется от другого объекта. – Deukalion

+1

@Deukalion: Ну, тогда вы можете использовать C#. C++ - это другой язык с различной семантикой. Я не думаю, что вам нужно * делать то, что вы говорите, это просто ваше восприятие, поскольку вы более опытны с тем, как все делается на C# и неопытным в C++. Вы по-прежнему проверяете время компиляции, чтобы аргумент шаблона поддерживал требуемый интерфейс, но не на уровне типа. –

+0

Я спросил, есть ли аналогичный способ получения тех же результатов вместо того, чтобы воспроизводить несколько классов. Например, если я хочу, чтобы T был базовым классом с методами, которые будет использовать класс, содержащий объект, но другой объект может расширить этот объект для своих целей, это означает, что объект должен знать только, что это объект, унаследованный от BaseClass. – Deukalion

0

Вы спрашиваете о Концепции C++, способ указания требований к параметрам шаблона. Они были предложены во время работы над C++ 11, но оказались достаточно сложными, что они не были выполнены вовремя. Но они только что были отложены, а не забыты.

В то же время, утиная печать остается очень мощной, и она будет ломаться, когда вы передадите параметр шаблона, который не имеет требуемого интерфейса. Он просто не сообщит о проблеме как аккуратно.

В качестве временного решения, простой способ проверить ограничение вы показали имеет преимущество в том, что преобразования указателей неявные только тогда, когда приведение к базовому типу:

public class Test<T> where T : BaseClass 
{ 
    static T* enforcement_helper = 0; 
    static BaseClass* enforce_inheritance_constraint = enforcement_helper; 

}; 

В зависимости от того, как новый компилятор, вы, возможно, потребуется поместите эти строки внутри специальной функции-члена (деструктор хорош, потому что он почти всегда обрабатывается).

Но вы должны только проверять ограничения, чтобы улучшить сообщения об ошибках (вызвав отказ в четко прокомментированном разделе кода). Шаблоны C++ печатаются утки, и они будут работать с любыми параметрами шаблона, которые обеспечивают требуемые операции. Формального «интерфейса» не требуется.

Смежные вопросы