Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Sınıf şablonları kısmen özelleştirilebilir ve sonuçta elde edilen sınıf hala bir şablondur. Kısmi özelleştirme, şablon kodunun bazı durumlarda belirli türler için kısmen özelleştirilmesine olanak tanır, örneğin:
Bir şablonun birden çok türü vardır ve yalnızca bazılarının özel olması gerekir. Sonuç, kalan türlerde parametrelendirilmiş bir şablondur.
Şablonun yalnızca bir türü vardır, ancak işaretçi, başvuru, üye işaretçisi veya işlev işaretçisi türleri için bir özelleştirme gerekir. Özelleştirmenin kendisi, işaret edilen veya başvuruda bulunan türdeki bir şablondur.
Örnek: Sınıf şablonlarının kısmi uzmanlığı
// partial_specialization_of_class_templates.cpp
#include <stdio.h>
template <class T> struct PTS {
enum {
IsPointer = 0,
IsPointerToDataMember = 0
};
};
template <class T> struct PTS<T*> {
enum {
IsPointer = 1,
IsPointerToDataMember = 0
};
};
template <class T, class U> struct PTS<T U::*> {
enum {
IsPointer = 0,
IsPointerToDataMember = 1
};
};
struct S{};
int main() {
printf_s("PTS<S>::IsPointer == %d \nPTS<S>::IsPointerToDataMember == %d\n",
PTS<S>::IsPointer, PTS<S>:: IsPointerToDataMember);
printf_s("PTS<S*>::IsPointer == %d \nPTS<S*>::IsPointerToDataMember == %d\n"
, PTS<S*>::IsPointer, PTS<S*>:: IsPointerToDataMember);
printf_s("PTS<int S::*>::IsPointer == %d \nPTS"
"<int S::*>::IsPointerToDataMember == %d\n",
PTS<int S::*>::IsPointer, PTS<int S::*>::
IsPointerToDataMember);
}
PTS<S>::IsPointer == 0
PTS<S>::IsPointerToDataMember == 0
PTS<S*>::IsPointer == 1
PTS<S*>::IsPointerToDataMember == 0
PTS<int S::*>::IsPointer == 0
PTS<int S::*>::IsPointerToDataMember == 1
Örnek: İşaretçi türleri için kısmi özelleştirme
Herhangi bir türü Talan bir şablon koleksiyonu sınıfınız varsa, herhangi bir işaretçi türünü T*alan kısmi bir özelleştirme oluşturabilirsiniz. Aşağıdaki kod, koleksiyon sınıfı şablonunu Bag ve koleksiyonun işaretçi türlerini diziye kopyalamadan önce başvuruda bulunduğu işaretçi türleri için kısmi özelleştirmeyi gösterir. Koleksiyon daha sonra işaret edilen değerleri depolar. Özgün şablonda, yalnızca işaretçilerin kendileri koleksiyonda depolanmış ve veriler silinmeye veya değişikliğe karşı savunmasız bırakılmıştır. Koleksiyonun bu özel işaretçi sürümünde, yönteminde add null işaretçi olup olmadığını denetlemek için kod eklenir.
// partial_specialization_of_class_templates2.cpp
// compile with: /EHsc
#include <iostream>
using namespace std;
// Original template collection class.
template <class T> class Bag {
T* elem;
int size;
int max_size;
public:
Bag() : elem(0), size(0), max_size(1) {}
void add(T t) {
T* tmp;
if (size + 1 >= max_size) {
max_size *= 2;
tmp = new T [max_size];
for (int i = 0; i < size; i++)
tmp[i] = elem[i];
tmp[size++] = t;
delete[] elem;
elem = tmp;
}
else
elem[size++] = t;
}
void print() {
for (int i = 0; i < size; i++)
cout << elem[i] << " ";
cout << endl;
}
};
// Template partial specialization for pointer types.
// The collection has been modified to check for NULL
// and store types pointed to.
template <class T> class Bag<T*> {
T* elem;
int size;
int max_size;
public:
Bag() : elem(0), size(0), max_size(1) {}
void add(T* t) {
T* tmp;
if (t == NULL) { // Check for NULL
cout << "Null pointer!" << endl;
return;
}
if (size + 1 >= max_size) {
max_size *= 2;
tmp = new T [max_size];
for (int i = 0; i < size; i++)
tmp[i] = elem[i];
tmp[size++] = *t; // Dereference
delete[] elem;
elem = tmp;
}
else
elem[size++] = *t; // Dereference
}
void print() {
for (int i = 0; i < size; i++)
cout << elem[i] << " ";
cout << endl;
}
};
int main() {
Bag<int> xi;
Bag<char> xc;
Bag<int*> xp; // Uses partial specialization for pointer types.
xi.add(10);
xi.add(9);
xi.add(8);
xi.print();
xc.add('a');
xc.add('b');
xc.add('c');
xc.print();
int i = 3, j = 87, *p = new int[2];
*p = 8;
*(p + 1) = 100;
xp.add(&i);
xp.add(&j);
xp.add(p);
xp.add(p + 1);
delete[] p;
p = NULL;
xp.add(p);
xp.print();
}
10 9 8
a b c
Null pointer!
3 87 8 100
Örnek: Bir tür olacak şekilde kısmi özelleştirme tanımlayın int
Aşağıdaki örnek, herhangi iki türden oluşan çiftleri alan bir şablon sınıfı tanımlar ve sonra bu şablon sınıfının türlerden biri olacak intşekilde özelleştirilmiş kısmi bir özelleştirme tanımlar. Özelleştirme, tamsayıya göre basit bir kabarcık sıralama uygulayan ek bir sıralama yöntemi tanımlar.
// partial_specialization_of_class_templates3.cpp
// compile with: /EHsc
#include <iostream>
using namespace std;
template <class Key, class Value> class Dictionary {
Key* keys;
Value* values;
int size;
int max_size;
public:
Dictionary(int initial_size) : size(0) {
max_size = 1;
while (initial_size >= max_size)
max_size *= 2;
keys = new Key[max_size];
values = new Value[max_size];
}
void add(Key key, Value value) {
Key* tmpKey;
Value* tmpVal;
if (size + 1 >= max_size) {
max_size *= 2;
tmpKey = new Key [max_size];
tmpVal = new Value [max_size];
for (int i = 0; i < size; i++) {
tmpKey[i] = keys[i];
tmpVal[i] = values[i];
}
tmpKey[size] = key;
tmpVal[size] = value;
delete[] keys;
delete[] values;
keys = tmpKey;
values = tmpVal;
}
else {
keys[size] = key;
values[size] = value;
}
size++;
}
void print() {
for (int i = 0; i < size; i++)
cout << "{" << keys[i] << ", " << values[i] << "}" << endl;
}
};
// Template partial specialization: Key is specified to be int.
template <class Value> class Dictionary<int, Value> {
int* keys;
Value* values;
int size;
int max_size;
public:
Dictionary(int initial_size) : size(0) {
max_size = 1;
while (initial_size >= max_size)
max_size *= 2;
keys = new int[max_size];
values = new Value[max_size];
}
void add(int key, Value value) {
int* tmpKey;
Value* tmpVal;
if (size + 1 >= max_size) {
max_size *= 2;
tmpKey = new int [max_size];
tmpVal = new Value [max_size];
for (int i = 0; i < size; i++) {
tmpKey[i] = keys[i];
tmpVal[i] = values[i];
}
tmpKey[size] = key;
tmpVal[size] = value;
delete[] keys;
delete[] values;
keys = tmpKey;
values = tmpVal;
}
else {
keys[size] = key;
values[size] = value;
}
size++;
}
void sort() {
// Sort method is defined.
int smallest = 0;
for (int i = 0; i < size - 1; i++) {
for (int j = i; j < size; j++) {
if (keys[j] < keys[smallest])
smallest = j;
}
swap(keys[i], keys[smallest]);
swap(values[i], values[smallest]);
}
}
void print() {
for (int i = 0; i < size; i++)
cout << "{" << keys[i] << ", " << values[i] << "}" << endl;
}
};
int main() {
Dictionary<const char*, const char*> dict(10);
dict.print();
dict.add("apple", "fruit");
dict.add("banana", "fruit");
dict.add("dog", "animal");
dict.print();
Dictionary<int, const char*> dict_specialized(10);
dict_specialized.print();
dict_specialized.add(100, "apple");
dict_specialized.add(101, "banana");
dict_specialized.add(103, "dog");
dict_specialized.add(89, "cat");
dict_specialized.print();
dict_specialized.sort();
cout << endl << "Sorted list:" << endl;
dict_specialized.print();
}
{apple, fruit}
{banana, fruit}
{dog, animal}
{100, apple}
{101, banana}
{103, dog}
{89, cat}
Sorted list:
{89, cat}
{100, apple}
{101, banana}
{103, dog}