Đối tượng foo
là biến địa phương có loại Foo*
. Biến đó có thể được phân bổ trên ngăn xếp cho hàm main
, giống như bất kỳ biến cục bộ nào khác. Nhưng giá trị được lưu trữ trong foo
là một con trỏ rỗng. Nó không trỏ đâu cả. Không có trường hợp nào của loại Foo
được biểu thị ở bất kỳ đâu.
Để gọi hàm ảo, người gọi cần biết đối tượng nào đang được gọi. Đó là bởi vì đối tượng chính nó là những gì cho biết chức năng nào thực sự nên được gọi. (Điều đó thường được thực hiện bằng cách cho đối tượng con trỏ đến vtable, danh sách các con trỏ hàm và người gọi chỉ biết rằng nó được gọi là hàm đầu tiên trong danh sách, mà không biết trước điểm trỏ đó.)
Nhưng để gọi một chức năng không phải ảo, người gọi không cần biết tất cả điều đó. Trình biên dịch biết chính xác hàm nào sẽ được gọi, vì vậy nó có thể tạo ra một mã lệnh máy mã CALL
để đi trực tiếp đến hàm mong muốn. Nó đơn giản chuyển một con trỏ tới đối tượng mà hàm được gọi là tham số ẩn cho hàm. Nói cách khác, trình biên dịch chuyển cuộc gọi chức năng của bạn vào đây:
void Foo_say_hi(Foo* this);
Foo_say_hi(foo);
Bây giờ, kể từ khi thực hiện chức năng mà không bao giờ làm cho tham chiếu đến bất kỳ thành viên của đối tượng được trỏ đến bởi this
đối số của nó, bạn có hiệu quả né tránh đạn của dereferencing một con trỏ null bởi vì bạn không bao giờ dereference một.
Chính thức, gọi bất kỳ chức năng nào - ngay cả một chức năng không ảo - trên con trỏ rỗng là hành vi không xác định. Một trong những kết quả được cho phép của hành vi không xác định là mã của bạn dường như chạy chính xác như bạn dự định. Bạn không nên dựa vào điều đó, mặc dù đôi khi bạn sẽ tìm thấy thư viện từ nhà cung cấp trình biên dịch của mình rằng làm dựa vào điều đó. Nhưng nhà cung cấp trình biên dịch có lợi thế là có thể thêm định nghĩa thêm vào những gì nếu không sẽ là hành vi không xác định. Đừng tự làm.
Nguồn
2009-03-21 18:53:42
Xem [this] (http://stackoverflow.com/questions/2474018/when-does-invoking-a-member-function-on-a-null-instance-result-in-undefined-behav) cho những gì ngôn ngữ nói về nó. Cả hai đều là hành vi không xác định. – GManNickG