Идея о том, как «смоделировать» атрибут класса с помощью специализации шаблона:
#include <string>
#include <iostream>
// attribute classes: the default implementation returns some
// default values for the attributes properties
template<typename TheClass>
struct Attribute1{
static const int Value = 0;
};
template<typename TheClass>
struct Attribute2{
static const std::string Value(){
return "";
}
};
Реализация атрибутов по умолчанию будет выбрана компилятором для класса без атрибутов:
// define a type without attributes
struct ClassWithoutAttributes{
};
Если мы хотим применить атрибуты к классу, мы используем специализацию шаблона:
// define a type with attributes; we "simulate" the attributes
// template specialization
struct ClassWithAttributes{
};
// template-specialize Attribute1 for the class we want to apply the
// attribute to...
template<>
struct Attribute1<ClassWithAttributes>{
static const int Value = 1;
};
// template-specialize Attribute2
template<>
struct Attribute2<ClassWithAttributes>{
static const std::string Value(){
return "SomeString";
}
};
Мы должны применять (шаблонно-специализированные) атрибуты для каждого класса, к которому мы хотим, чтобы они применялись:
class Item{
};
template<>
struct Attribute1<Item>{
static const int Value = 2;
};
Пример:
// how to use the fake attributes:
void main(){
// no template specialization for "ClassWithoutAttributes" => the compiler picks up the "default" values
std::cout << "Attribute1 for type 'ClassWithoutAttributes' : " << Attribute1<ClassWithoutAttributes>::Value << std::endl;
std::cout << "Attribute2 for type 'ClassWithoutAttributes' : " << Attribute2<ClassWithoutAttributes>::Value() << std::endl;
// here the compiler picks up the attribute classes specialized for "ClassWithAttributes"
std::cout << "Attribute1 for type 'ClassWithAttributes' : " << Attribute1<ClassWithAttributes>::Value << std::endl;
std::cout << "Attribute2 for type 'ClassWithAttributes' : " << Attribute2<ClassWithAttributes>::Value() << std::endl;
}
Таким образом, атрибуты «применяются» к классу, а не к экземпляру, как при множественном наследовании; в любом случае принципиальное отличие состоит в том, что в этом случае атрибуты оцениваются во время компиляции, а не во время выполнения.
РЕДАКТИРОВАТЬ : изменил пример, чтобы показать, как применять несколько атрибутов к классу и как применять один и тот же атрибут к нескольким классам.
Отвечать на этот вопрос было весело для меня; на данный момент, во всяком случае, я чувствую, что лучший совет по этому вопросу заключается в том, что вы не должны пытаться программировать на c ++, как если бы это был c #. В любом случае, удачного кодирования!