2012-04-15 26 views
6

Câu hỏi của tôi khá đơn giản. Tôi có một TList (gọi là queue) chứa các đối tượng của lớp CNotif và muốn sử dụng phương thức is_alive trên các đối tượng đó.Làm thế nào để sử dụng một phương pháp của một đối tượng được lưu trữ trong TList?

Vấn đề là khi tôi sử dụng queue.Items[0].is_alive(), tôi nhận được thông báo lỗi cho biết Error: Illegal qualifier.

Tôi cũng bối rối với cách tôi có thể nhanh chóng đối tượng trong TList này (và làm thế nào cách trình biên dịch "biết" rằng các đối tượng được lưu trữ là thuộc loại này ...)

Những gì tôi làm bây giờ là : queue.Add(CNotif.create(timer, title, text, badge)) nhưng tôi không nghĩ rằng nó phải được thực hiện theo cách đó.

Cảm ơn bạn trước!

+4

Chỉ cần một phụ trang. Có một quy ước bất thành văn để đặt tên các kiểu với char đầu tiên 'T', giống như' TLama' là kiểu 'Lama', vì vậy đối với trường hợp của bạn, nó sẽ là' TCNotif' ;-) – TLama

+0

Không phải là C cho Lớp và T cho các loại "cơ bản" (như một mảng hoặc bản ghi)? – halflings

+0

Không, nó dành cho tất cả 'T'ypes, bao gồm các lớp, bản ghi, liệt kê vv Hãy nói cho mọi thứ bạn có trong phần' loại' của mã của bạn. – TLama

Trả lời

10

The problem is, when I use queue.Items[0].is_alive(), I get an error message saying Error: Illegal qualifier.

Đó là do trình biên dịch không biết queue.items[0] nào khác với con trỏ chung (xem bên dưới).

What I do now is: queue.Add(CNotif.create(timer, title, text, badge)) but I don't think it's supposed to be done that way.

Đây chính là cách bạn cần thực hiện. CNotif.Create tạo đối tượng mới và đối tượng đó xuống từ TObject. Nó biên dịch tốt vì cuộc gọi queue.Add của bạn đang mong đợi một con trỏ, và một biến Delphi/FreePascal chứa một cá thể đối tượng thực sự là một con trỏ. (Cả hai ngôn ngữ ẩn cần phải dereference sử dụng MyObj^ cho chúng ta.)

Để sử dụng một cái gì đó trong queue.Items, bạn cần phải nói với trình biên dịch những gì trong đó khác hơn là một generic pointer (trong đó tất nhiên không có một phương pháp is_alive) . Bạn làm điều đó bằng cách gõ:

CNotif(queue.Items[0]).is_alive 

Lưu ý: Có cách ngắn hơn để sử dụng TList.Items; Items được khai báo là thuộc tính mặc định cho TList, vì vậy bạn có thể bỏ qua nó:

queue[0] 

cũng giống như

queue.Items[0] 

và dễ dàng hơn nhiều để gõ.

+0

Câu trả lời hay! :) Cảm ơn rất nhiều. – halflings

+3

Thành viên của 'TList' không phải là' Tobject' nhưng là con trỏ. – NGLN

+0

Điểm tốt. :) Lỗi của tôi; đã viết quá nhanh và phải nghĩ đến 'TObjectList'. Tôi sẽ sửa nó. Cảm ơn. :) –

6

Trừ khi bạn đang mắc kẹt với một phiên bản Delphi cũ, bạn nên nhìn vào generics.

Trong đơn vị generics.collection có một lớp học TList<T> mà bạn có thể sử dụng tại đây.

Queue:TList<CNotify>; 

... 
Begin 
    Queue := TList<CNotify>.Create; // remember to clean it up 
    Queue.Add(CNotify.Create(...)); 
    Queue.Add(CNotify.Create(...)); 

    If Queue[0].isAlive then 
    Beep; 
End; 

Tôi chưa sử dụng fpc và lazarus trong một thời gian, nhưng ở Delphi, đây chắc chắn là cách để làm điều này. Danh sách các con trỏ không được phân loại và loại phôi trên khắp nơi có thể trở thành một cơn ác mộng để duy trì.

+2

+1, nhưng nó có thể là tốt để đề cập đến từ D2010 + vì có một số vấn đề trong D2009 đặc biệt là với 'TList'. – TLama

+4

Trong chế độ ff ObjFPC, cú pháp là 'loại TQueue = chuyên TFPGList ' - nhưng bạn cũng có thể sử dụng chế độ Delphi có cú pháp Delphi (ít nhất là từ 2.6). – lukstafi

Các vấn đề liên quan