2012-05-02 37 views
5

Tôi bắt đầu học Delphi hai ngày trước nhưng tôi bị kẹt. Tôi đã phá vỡ vì không có gì đi theo cách của tôi vì vậy tôi quyết định viết ở đây. Tôi muốn tạo ra một lớp có một trường với đối tượng TTimer của riêng nó và nó sẽ thực hiện một số hành động trong một khoảng thời gian nào đó. Thậm chí có thể không? Giả sử chúng tôi có mã như vậy:Đối tượng TTimer có thể là một trường của lớp Delphi không?

Sth = class 
private 

public 
    clock:TTimer; 
    procedure clockTimer(Sender: TObject); 
    constructor Create(); 
end; 

constructor Sth.Create() 
begin 
    clock.interval:=1000; 
    clock.OnTimer := clockTimer; 
end; 

procedure Sth.clockTimer(Sender: TObject); 
begin 
    //some action on this Sth object at clock.interval time... 
end; 

Copiles mã tương tự của tôi nhưng không hoạt động bình thường. Khi tôi gọi hàm khởi tạo chương trình bị treo (truy cập vi phạm tại dòng: clock.interval: = 1000;). Tôi không biết những gì

Sender:TObject 

nhưng tôi nghĩ đó không phải là vấn đề. Tôi có thể tạo lớp học như vậy không?

+0

Bộ xử lý là trường rất thường xuyên của các lớp Delphi. Các lớp biểu mẫu là các lớp và mỗi khi bạn đặt một TTimer trên một biểu mẫu, IDE sẽ khai báo một trường TTimer cho bạn. –

+0

Tôi biết rằng IDE khai báo trường TTimer cho tôi khi tôi đặt nó trên một biểu mẫu. Nhưng tôi muốn đặt TTimer là một lĩnh vực không có hình thức. Tôi muốn viết một lớp riêng biệt (* .pas) mà không có biểu mẫu và liên kết nó với biểu mẫu chính. Vì vậy, không có hình thức, tôi đã phải viết tất cả các tờ khai của riêng tôi. Tôi không biết nếu đó là cách tiếp cận tốt (không sử dụng mẫu với các lớp trung học), tôi thậm chí không biết vấn đề của các hình thức nào được nêu ra. Nhưng bây giờ mọi thứ đều hoạt động tốt sau khi David Heffernan trả lời. – xan

+0

Vấn đề cơ bản này (bạn không biết rằng bạn phải tạo đối tượng trước khi bạn sử dụng nó) cho tôi biết bạn có thể hưởng lợi từ việc đọc một số tài liệu cơ bản, như vài chương đầu tiên của một trong những cuốn sách Delphi cũ như Marco cantu một (làm chủ delphi 7 hoặc một cái gì đó như thế), hoặc ít nhất, chi tiêu một số thời gian nhiều hơn tại http://www.delphibasics.co.uk/ –

Trả lời

12

Bạn chưa tạo bộ hẹn giờ. Khai báo một biến là không đủ. Bạn cần tạo bộ hẹn giờ.

constructor Sth.Create() 
begin 
    clock := TTimer.Create(nil); 
    clock.interval:=1000; 
    clock.OnTimer := clockTimer; 
end; 

Và bạn cũng nên phá hủy nó. Thêm một destructor lớp

destructor Destroy; override; 

và thực hiện nó như thế này

destructor Sth.Destroy; 
begin 
    clock.Free; 
    inherited; 
end; 

Tôi cũng sẽ khuyên bạn nên làm cho lĩnh vực clock của bạn có tầm nhìn riêng. Nó không tốt để lộ các lớp bên trong của một lớp như thế.

TMyClass = class 
private 
    FClock: TTimer; 
    procedure ClockTimer(Sender: TObject); 
public 
    constructor Create; 
    destructor Destroy; override; 
end; 
.... 
constructor TMyClass.Create 
begin 
    inherited; 
    FTimer := TTimer.Create(nil); 
    FTimer.Interval := 1000; 
    FTimer.OnTimer := ClockTimer; 
end; 

destructor TMyClass.Destroy; 
begin 
    FTimer.Free; 
    inherited; 
end; 

Lưu ý rằng tôi đã bao gồm các cuộc gọi đến hàm tạo và hàm hủy kế thừa. Đây không phải là cần thiết trong lớp này vì nó xuất phát trực tiếp từ TObject và hàm tạo và hàm hủy cho TObject trống. Nhưng nếu bạn thay đổi thừa kế tại một số điểm, và làm cho lớp của bạn xuất phát từ một lớp khác, thì bạn sẽ cần phải làm điều này. Vì vậy, theo quan điểm của tôi, thực hành tốt là luôn luôn bao gồm các cuộc gọi này.

+0

dòng: đồng hồ: = TTimer.Create; không biên dịch. Nó nói: "Không đủ thông số thực tế". – xan

+0

Bây giờ mọi thứ đều ổn. Nhưng câu hỏi cuối cùng: Tại sao TTimer.Create (nil)? Làm thế nào quan trọng là nil ở đây? Tại sao chúng ta phải viết nó? Cảm ơn bạn rât nhiêu! :-) – xan

+3

Hàm tạo nhận một tham số có tên Chủ sở hữu loại TComponent. Nếu lớp của bạn bắt nguồn từ 'TComponent' thì nó có thể truyền' Self' và sau đó instance của bạn sẽ * sở hữu * timer. Điều đó có nghĩa là bộ hẹn giờ sẽ tự động bị hủy khi chủ nhân của nó bị phá hủy. Điều này được sử dụng rộng rãi trong VCL. Nó không cần thiết ở đây, do đó bạn vượt qua 'nil' để chọn không tham gia cơ chế sở hữu. –

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