2013-07-31 41 views
10

Tôi nhận thấy rằng hàm tạo sẽ di chuyển this đến eax trước khi trở về. Đây là một giá trị trả lại hay cái gì khác?tại sao các nhà thầu "trả lại" con trỏ này?

class CTest { 
    int val_; 
public: 
    CTest() { 
0093F700 push  ebp 
0093F701 mov   ebp,esp 
0093F703 sub   esp,0CCh 
0093F709 push  ebx 
0093F70A push  esi 
0093F70B push  edi 
0093F70C push  ecx 
0093F70D lea   edi,[ebp-0CCh] 
0093F713 mov   ecx,33h 
0093F718 mov   eax,0CCCCCCCCh 
0093F71D rep stos dword ptr es:[edi] 
0093F71F pop   ecx 
0093F720 mov   dword ptr [this],ecx 
     val_ = 1; 
0093F723 mov   eax,dword ptr [this] 
0093F726 mov   dword ptr [eax],1 
    } 
0093F72C mov   eax,dword ptr [this] 
0093F72F pop   edi 
0093F730 pop   esi 
0093F731 pop   ebx 
0093F732 mov   esp,ebp 
0093F734 pop   ebp 
0093F735 ret 

VS2012 chế độ gỡ lỗi


tôi thấy rằng new sẽ sử dụng "giá trị trả về" của nó. Có vẻ như if(operator new() == 0) return 0; else return constructor();

class CTest { 
    int val_; 
public: 
    CTest() { 
     val_ = 1; 
     __asm { 
      mov   eax, 0x12345678 
      pop   edi 
      pop   esi 
      pop   ebx 
      mov   esp,ebp 
      pop   ebp 
      ret 
     } 
    } 
}; 

int main() { 
    CTest *test = new CTest; // test == 0x12345678 
    return 0; 
} 
+2

Các nhà xây dựng không trả lại bất cứ điều gì, họ chỉ cho bạn cơ hội để khởi tạo đối tượng đang được tạo. –

+0

Đó là một dự đoán hoang dã, nhưng tôi đoán nó hỗ trợ xây dựng các lớp con. – Mehrdad

+17

Đây là chi tiết triển khai. Mỗi C ​​++ constructor tiêu chuẩn không trả lại bất cứ điều gì và bạn không nên dựa vào đó. [một số cuộc thảo luận SO liên quan] (http://stackoverflow.com/questions/10356109/c-constructors-have-no-return-type-just-exactly-why) – Tony

Trả lời

1

Câu hỏi thứ hai của bạn không đồng ý với câu hỏi đầu tiên của bạn. Làm cách nào để new sử dụng if (operator new() == 0) return 0; else return constructor(); nếu constructor() đang tạo kết quả điều kiện?

Dù sao ...

  1. gì trình biên dịch không có đăng ký là kinh doanh của trình biên dịch. Đăng ký có xu hướng giữ bất kỳ thông tin nào hữu ích ngay lập tức và nếu trình biên dịch được viết với niềm tin rằng mỗi khi hàm tạo được sử dụng, đối tượng được sử dụng ngay sau đó, nó có thể chọn một cách hợp lý để đặt this trong sổ đăng ký.

    ABI có thể yêu cầu người xây dựng thực hiện việc này, nhưng tôi nghi ngờ là có. Dù sao, các giao thức như vậy chỉ áp dụng cho những thứ được xuất từ ​​thư viện, chứ không phải trong các chương trình.

  2. Mọi biểu thức new không kiểm tra kết quả của operator new trước 0 trước khi tiếp tục khởi tạo đối tượng. operator new có thể báo hiệu lỗi bằng cách trả lại nullptr (hoặc NULL, v.v.).

    Điều này thực sự có thể là một vấn đề với vị trí biểu thức mới, bởi vì nó đại diện cho chi phí thời gian chạy không thể tránh khỏi như con trỏ đã cho thường được biết là không null.

0

Đây có thể là một tính năng do thiết kế, trong C++ và ngôn ngữ khác, trả lại một tham chiếu đến một trường hợp cho phép việc sử dụng "thành ngữ" hơn trong những tính năng được cung cấp bởi các đối tượng chính nó, trong ngắn hạn đó là Named parameter Idiom. Tuy nhiên, đây chỉ là 1 tùy chọn, đôi khi nó có thể hữu ích, đặc biệt nếu bạn có thể thiết kế thư viện của mình theo cách nó chỉ "thực hiện hành động" mà không cần phải truyền một lượng thông số đáng kể, do đó, chuỗi các cuộc gọi phương thức vẫn có thể đọc được.

+1

Một hàm tạo không bao giờ có giá trị trả lại. Một hàm trả về một cá thể sẽ là một hàm nhà máy, không phải là một hàm tạo. Trả về một tham chiếu * cho một đối tượng mới, thay vì trả về đối tượng, trong C++ là một lỗi trừ khi đối tượng được phân bổ cụ thể bằng cách nào đó. – Potatoswatter

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