Mẫu C++ nổi tiếng với việc lấy các loại làm đối số, nhưng chúng cũng có thể được tham số hóa trên các loại dữ liệu khác. Ví dụ, bạn có thể templatize một lớp trên một số nguyên, như thể hiện ở đây:
template <typename T, unsigned int N> class Array {
private:
T array[N];
public:
/* ... */
};
Templates cũng có thể được tham số qua con trỏ, miễn là con trỏ đáp ứng tiêu chí nhất định (ví dụ, nó có để đánh giá đến một địa chỉ của một cái gì đó có thể được xác định tại thời gian biên dịch).Ví dụ, đây là hoàn toàn hợp pháp:
template <int* Pointer> class ThisIsLegal {
public:
void doSomething() {
*Pointer = 137;
}
};
Trong code của bạn, các mẫu được tham số hóa hơn một con trỏ-to-đẳng cấp thành viên. Một thành viên lớp-con trỏ tương tự như một con trỏ ở chỗ nó gián tiếp đề cập đến một số đối tượng. Tuy nhiên, thay vì trỏ đến một đối tượng, thay vào đó nó trỏ đến một trường trong một lớp. Ý tưởng là bạn có thể dereference một con trỏ-to-class-thành viên liên quan đến một số đối tượng để chọn lĩnh vực đó ra khỏi lớp. Dưới đây là một ví dụ đơn giản của con trỏ-to-class thành viên:
struct MyStruct {
int x, y;
};
int main() {
MyStruct ms;
ms.x = 137;
ms.y = 42;
int MyStruct::* ptr; // Declare a pointer to a class member.
ptr = &MyStruct::x; // Now points to the field 'x'
ms.*ptr = 0; // Set the 'x' field of ms to be zero.
}
ý rằng cú pháp cho tuyên bố một con trỏ-to-đẳng cấp thành viên là
Type ContainingClass::* pointerName;
Vì vậy, trong đoạn mã trên, int MyStruct::* ptr
phương tiện . "một con trỏ đến một int
bên trong một MyStruct
lớp
trong mã mà bạn đã đăng, tờ khai mẫu lần đọc như thế này:
template <
class PropObject,
class PropType,
PropType PropObject::* Prop
>
class PropReader
Hãy xem ý nghĩa của điều này. Đối tượng đầu tiên hai đối số mẫu có thuộc tính sẽ được đọc và PropType
, loại thuộc tính đó. "Đối số cuối cùng cho mẫu là một thành viên lớp con trỏ có tên là Prop
trỏ vào bên trong một PropObject
tại một trường gõ PropType
Ví dụ, bạn có thể nhanh chóng mẫu này với MyStruct
như thế này:.
PropReader<MyStruct, int, &MyStruct::x> myPropReader;
Bây giờ, chúng ta hãy xem những gì còn lại của mã không phần nội dung của lớp mẫu này được in lại ở đây:.
void print(Object& o)
{
PropObject& po = static_cast<PropObject &>(o);
PropType& t = po.*Prop;
cout << t << "\n";
}
Một số điều này có thể được đọc khá dễ dàng. eter để chức năng này là một tham chiếu đến một Object
có tên o
, và dòng cuối cùng in ra một số lĩnh vực. Hai dòng này là rất phức tạp:
PropObject& po = static_cast<PropObject &>(o);
PropType& t = po.*Prop;
dòng đầu tiên này là một thợ đúc chư nói rằng "cố gắng đúc lập luận o
đến một tài liệu tham khảo của loại PropObject
Ý tưởng, tôi đoán, là Object
là một số lớp cơ sở. Tham số cho hàm chỉ là một đơn giản Object
, và dàn diễn viên này cố gắng chuyển đổi nó thành một cái gì đó của loại thích hợp (nhớ rằng PropObject
là đối số mẫu cho biết loại đối tượng là gì). điều này sử dụng static_cast
, nếu chuyển đổi không được xác định (ví dụ: bạn đã cố gắng tạo mẫu trên int
hoặc vector<string>
), mã sẽ không biên dịch. e, mã tin tưởng rằng dàn diễn viên là an toàn, sau đó nhận được một tham chiếu của loại PropObject
đến tham số tham chiếu.
Cuối cùng, dòng cuối cùng là
PropType& t = po.*Prop;
này sử dụng cú pháp dereference con trỏ-to-lớp-viên tôi đã đề cập trước đó để nói "chọn lĩnh vực được trỏ tới bởi Prop
(mẫu tham số), sau đó cửa hàng một tham chiếu đến nó có tên là t
.
Vì vậy, trong ngắn hạn, các mẫu
- yêu cầu bạn cho các loại của một số đối tượng.
- Yêu cầu bạn nhập loại trường nào đó trong đối tượng đó.
- Yêu cầu bạn trỏ đến trường trong đối tượng đó.
- Cung cấp chức năng
print
cho một đối tượng cố gắng in ra trường đó.
Whew! Đó là khó khăn! Hi vọng điêu nay co ich!
Đó là một câu trả lời tuyệt vời templatetypedef .. không có thắc mắc bạn có tên người dùng đó :) – cgcoder