2 sao là con trỏ tới con trỏ đó :V ConNguoi*[5] là mảng chứa 5 con trỏ tới con người, để tránh cn + i nó hiểu là cn + 54i. Khi cn là con trỏ tới con trỏ tới con người thì cn + i là cn + 8i (giả sử size con trỏ là 8), cn[i] là con trỏ tới con người thứ i.
để xài đa hình thì em phải để mọi thứ là Base* (hoặc Base&) chứ ko phải Base. Ở đây em xài mảng nên tốn thêm 1 cấp con trỏ nữa (Base*) *
(ConNguoi*)* cn = new (ConNguoi*)[5];
for(int i = 0 ; i < 5 ; i++) {
cn[i] = new SinhVien; // cn[i] là (ConNguoi*)
cn[i]->nhap();
}
// khi dọn dẹp phải xóa dừng SinhVien rồi mới xóa mảng chứa con trỏ
for(int i = 0 ; i < 5 ; i++) delete cn[i]; // cn[i] ko trỏ tới mảng nên chỉ xài `delete` là đủ
delete[] cn; // cn là mảng nên phải xài `delete[]`
còn vì sao phải xài Base* mà ko xài trực tiếp Base là vì Base có size cố định :V Ví dụ sizeof(Base) = B. Trong khi các lớp kế thừa từ Base là Derived1, Derived2 có thể có kích cỡ khác Base và khác nhau đôi một nữa :V B != D1, B != D2, D1 != D2 chẳng hạn. Khi tạo 1 mảng chỉ chứa n Base thì C++ nó rất thật thà tạo đúng n*B bytes :V Nếu em muốn chứa mảng gồm Base-Derived1-Derived2-Derived2-Derived1-Base-Derived1 sẽ ko tạo được, vì nó có kích cỡ ko đều: [B][D1][D2][D2][D1][B][D1] mà phải tạo mảng gồm con trỏ Base: Base*-Base*-Base*-Base*-Base*-Base*-Base*, mỗi con trỏ trỏ tới Base hoặc Derived1, Derived2 tùy thích. Khi này kích thước trong mảng đều giống như là 8 chẳng hạn: [8][8][8][8][8][8][8]
Hay mảng chứa n Derived1 thì nó tạo mảng đúng n*D1 bytes, phần tử thứ i sẽ cách phần tử đầu tiên D1*i bytes. Vì vậy nếu xài con trỏ Base* b trỏ tới mảng Derived1 này sẽ chạy ko đúng vì b + i nó hiểu là phần tử cách b đúng B*i bytes, trong khi phần tử thứ i trong mảng Derived1 nằm cách phần tử đầu tiên D1*i bytes, nếu B != D1 thì lỗi, thậm chí B==D1 vẫn có thể có lỗi :V Cách xử lý là xài thêm 1 cấp con trỏ nữa cho kích cỡ nó đồng đều, vì con trỏ tới kiểu X Y Z gì thì cũng chỉ có kích cỡ của con trỏ là 8 bytes (4 bytes nếu compile target 32-bit)
cn trỏ sai:
địa chỉ: ? ?+78 ?+78*2 ?+78*3 ?+78*4
mảng: [SinhVien1][SinhVien2][SinhVien3][SinhVien4][SinhVien5]
^ ^ ^ ^ ^
con trỏ cn cn+1 cn+2 cn+3 cn+4
giá trị ? ?+54 ?+54*2 ?+54*3 ?+54*4
cn = con trỏ tới (ConNguoi)
cn trỏ đúng:
địa chỉ: ? ?+8 ?+8*2 ?+8*3 ?+8*4
mảng: [ConNguoi* 1][ConNguoi* 2][ConNguoi* 3][ConNguoi* 4][ConNguoi* 5]
^ ^ ^ ^ ^
con trỏ cn cn+1 cn+2 cn+3 cn+4
giá trị ? ?+8 ?+8*2 ?+8*3 ?+8*4
cn = con trỏ tới (ConNguoi*)
ConNguoi* i có thể trỏ đến ConNguoi hoặc SinhVien tùy ý