Đây có phải là một hàm tạo kiểu C ++ cũ không?


17

Đây là một đoạn mã C ++.

Trong ví dụ này, nhiều khối mã trông giống như các lệnh gọi của hàm tạo. Thật không may, mã khối # 3 không phải (Bạn có thể kiểm tra nó bằng cách sử dụng https://godbolt.org/z/q3rsxnhttps://cppinsights.io ).

Tôi nghĩ rằng, đó là một ký hiệu C ++ cũ và nó có thể giải thích việc giới thiệu ký hiệu xây dựng C ++ 11 mới bằng cách sử dụng {} (cf # 4).

Bạn có một lời giải thích cho T(i)ý nghĩa, rất gần với một ký hiệu xây dựng, nhưng chắc chắn rất khác nhau?

struct T {
   T() { }
   T(int i) { }
};

int main() {
  int i = 42;
  {  // #1
     T t(i);     // new T named t using int ctor
  }
  {  // #2
     T t = T(i); // new T named t using int ctor
  }
  {  // #3
     T(i);       // new T named i using default ctor
  }
  {  // #4
     T{i};       // new T using int ctor (unnamed result)
  }
  {  // #5
     T(2);       // new T using int ctor (unnamed result)
  }
}

NB: do đó, T(i)(# 3) tương đương với T i = T();


1
Tôi nghĩ rằng tất cả các tuyên bố của bạn là chính xác.
Arne J


Lưu ý rằng trình biên dịch sẽ cho bạn biết khá nhiều tất cả những gì bạn cần biết nếu bạn chỉ hỏi nó: Thêm -Wallbạn nhận được " warning: parentheses were disambiguated as redundant parentheses around declaration of variable named 'i' [-Wvexing-parse]" từ tiếng kêu, hoặc " warning: unnecessary parentheses in declaration of 'i' [-Wparentheses]" ít động lực hơn " từ gcc .
Max Langhof

@QuentinUK cảm ơn bạn đã liên kết này. Tôi đã nhận thức được nó về các hàm (ví dụ T t()) nhưng không phải là biểu thức khai báo đơn giản như vậy. Để chắc chắn, điều này có thể là bực tức .
Pascal H.

Câu trả lời:


17

Tuyên bố:

T(i);

tương đương với:

T i;

Nói cách khác, nó khai báo một biến có tên là itype T. Điều này là do dấu ngoặc đơn được cho phép trong khai báo ở một số nơi (để thay đổi ràng buộc của người khai báo) và vì tuyên bố này có thể được phân tích cú pháp như một tuyên bố, nó là một tuyên bố (mặc dù nó có thể có ý nghĩa hơn như một biểu thức).


Vì vậy, đây có phải chỉ là một lựa chọn giải thích được kế thừa từ thông số kỹ thuật C trong đó int(i)cũng tuyên bố một inttên i?
Pascal H.

@PascalH. Từ một quan điểm nhất định, điều đó có thể đúng. Stroustrup đã viết trong D & E rằng ông đã xem xét một cú pháp khai báo thay thế, trực quan hơn cho C ++. Nếu C ++ không phải tương thích ngược với C, thì có lẽ nó sẽ có cú pháp thay thế, và do đó tránh được sự mơ hồ tiềm ẩn với các biểu thức.
Brian

-1

Bạn có thể dùng Compiler Explorer để xem những gì xảy ra trong trình biên dịch chương trình .

Bạn có thể thấy rằng # 1, # 2 # 4 và # 5 làm điều tương tự nhưng lạ lùng # 3 gọi hàm tạo khác (hàm tạo đối tượng cơ sở).

Có ai có một lời giải thích?

Mã biên dịch:

::T() [base object constructor]:
        push    rbp
        mov     rbp, rsp
        mov     QWORD PTR [rbp-8], rdi
        nop
        pop     rbp
        ret
T::T(int):
        push    rbp
        mov     rbp, rsp
        mov     QWORD PTR [rbp-8], rdi
        mov     DWORD PTR [rbp-12], esi
        nop
        pop     rbp
        ret
main:
        push    rbp
        mov     rbp, rsp
        sub     rsp, 16
        mov     DWORD PTR [rbp-4], 42
// #1
        mov     edx, DWORD PTR [rbp-4]
        lea     rax, [rbp-7]
        mov     esi, edx
        mov     rdi, rax
        call    T::T(int)
// #2
        mov     edx, DWORD PTR [rbp-4]
        lea     rax, [rbp-8]
        mov     esi, edx
        mov     rdi, rax
        call    T::T(int)
// #3
        lea     rax, [rbp-9]
        mov     rdi, rax
        call    T::T() [complete object constructor]
// #4
        mov     edx, DWORD PTR [rbp-4]
        lea     rax, [rbp-6]
        mov     esi, edx
        mov     rdi, rax
        call    T::T(int)
// #5
        lea     rax, [rbp-5]
        mov     esi, 2
        mov     rdi, rax
        call    T::T(int)

        mov     eax, 0
        leave
        ret
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.