2014-04-23 26 views
5

Trong C++, một tổng hợp được (lấy từ 8.5.1p1 của spec ngôn ngữ)C++ tổng hợp không có chức năng ảo?

một mảng hoặc một lớp học (khoản 9) không có nhà xây dựng người dùng cung cấp (12.1), không có cá nhân hay không được bảo vệ thành viên dữ liệu -static (Điều 11), không có các lớp cơ sở (Điều 10), và không có chức năng ảo (10.3).

Vì vậy, #1 không phải là tổng hợp, nhưng #2 là tổng hợp. Tại sao #1 không phải là tổng hợp?

struct A { virtual void bark() { } int a; }; // #1 
struct B { A b; }; // #2 
+3

"[..] và không có chức năng ảo (10.3)"? – MrDuk

+0

Trích dẫn của bạn "không có chức năng ảo" cho chúng tôi biết rằng đó là tổng hợp. – harper

+0

@MrDuk Có, tôi có thể xác minh rằng đây là phần cuối cùng của văn bản mà tôi đã trích dẫn. Hay bạn muốn hỏi một câu hỏi khác? –

Trả lời

5

Tại sao # 1 không phải là tổng hợp?

Bởi vì định nghĩa chuẩn của tập hợp nói rằng nó không phải là. Định nghĩa nói rằng lớp không thể có các hàm ảo nếu nó được coi là một loại tổng hợp. Đó là nó. Đó là câu trả lời "đội trưởng rõ ràng".

Vì bạn trích dẫn định nghĩa chuẩn (và đọc nó, tôi đoán), bạn biết điều này rồi, vì vậy tôi phải giả định rằng những gì bạn đang hỏi là có lý do cơ bản nào không. kiểu.

Rõ ràng, một lớp có chức năng ảo phải có con trỏ bảng ảo (hoặc cơ chế khác) được khởi tạo như một phần của hàm tạo được trình biên dịch tạo ra. Và điều duy nhất mà cốt liệu thực sự cung cấp (ngoài việc phục vụ như là một định nghĩa cơ sở cho POD và những thứ tương tự) là khả năng thực hiện khởi tạo xoăn của các thành viên dữ liệu của nó. Tôi không thấy bất kỳ lý do tại sao trình biên dịch có thể không chỉ đơn giản cho phép cú pháp khởi tạo xoăn xoắn trong khi thực hiện khởi tạo con trỏ bảng ảo quá.

Có liên quan, nó có thể là tổng hợp vì khởi tạo cú đúp có thể miễn là có cách để xây dựng các thành viên dữ liệu từ bất kỳ thứ gì được cung cấp (hoặc không được cung cấp) trong danh sách khởi tạo, tức là , nó cần mỗi thành viên dữ liệu để có một số (mặc định biên dịch tạo ra hay không) mặc định, sao chép hoặc di chuyển constructor. Hãy nhớ rằng, định nghĩa của tổng hợp là nông ngược với đệ quy như định nghĩa POD (tầm thường, bố cục std), có nghĩa là chỉ có lớp cấp cao nhất có những hạn chế đó chứ không phải các đối tượng phụ của nó.

Định nghĩa cốt liệu rõ ràng là rất gợi nhớ về các hạn chế cấu trúc C, và khởi tạo cú đúp cho cấu trúc rõ ràng cũng là một tính năng được chuyển từ C. Tôi tin rằng vì lý do lịch sử, định nghĩa của tập hợp được xây dựng sao cho nó phản ánh cấu trúc C, chứ không phải vì lý do gì hoặc không thể cho trình biên dịch thực hiện.

Tôi chắc chắn sẽ có ý kiến ​​rằng không có lý do chính đáng nào cho việc hạn chế tổng hợp không có chức năng ảo. Có lẽ một đề nghị nên được thực hiện cho ủy ban tiêu chuẩn để loại bỏ hạn chế này (vì nó sẽ không phá vỡ bất kỳ mã hiện có nào). Đặc biệt bây giờ, với cú pháp khởi tạo thống nhất, tổng hợp không có gì khác ngoài các lớp mà trình biên dịch có thể tạo ra một hàm tạo với tất cả các thành viên dữ liệu làm tham số (với các giá trị mặc định là các đối tượng được xây dựng mặc định). Mục đích duy nhất cho cốt liệu là gộp một vài hạn chế áp dụng cho các lớp POD (tầm thường, bố cục chuẩn, v.v.), mà hạn chế không có chức năng ảo là hợp lý (AFAIK), nhưng đó chỉ là vấn đề chuyển giới hạn đó sang POD.

+1

* Rõ ràng, một lớp với các hàm ảo phải có con trỏ bảng ảo được khởi tạo như là một phần của hàm tạo được trình biên dịch. * => Tôi muốn chỉ ra rằng C++ Standard không ủy quyền sử dụng một bảng ảo, và do đó một ảo con trỏ bảng. Đó là, thực sự, một thực hiện rất phổ biến của cơ chế công văn 'ảo', và như vậy nặng trên tất cả các quyết định xung quanh xử lý' ảo', nhưng nó là * chỉ * một chi tiết thực hiện. –

+0

@MatthieuM. Chắc chắn, đó là sự thật. Nhưng logic là như nhau bất kể chi tiết thực hiện. Nếu trình biên dịch có thể tạo ra một hàm khởi tạo mặc định (hoặc một hàm tạo mặc định với các bộ khởi tạo thành viên trong lớp) cho bất kỳ lớp nào (bao gồm các hàm ảo), thì nó có thể tạo ra một hàm tạo được sử dụng với cú pháp khởi tạo cú đúp tổng hợp. Tôi nghĩ rằng các hạn chế chức năng ảo chỉ đơn giản là đặt không đúng chỗ trong tiêu chuẩn, nó nên được chỉ cho các định nghĩa POD, không cho cốt liệu. –

+1

Yêu cầu tổng hợp POD-ness trong C++ 03 (C++ 03 [lớp]/4), điều đó không còn là trường hợp.POD được định nghĩa là đệ quy * tầm thường * và * tiêu chuẩn bố trí * (C++ 11 [lớp]/10), không phải trong số đó đòi hỏi phải là một tổng hợp. Có thể cho một lớp/công đoàn là cả POD và tổng hợp, nhưng không bắt buộc. Loại bỏ các hạn chế về chức năng ảo từ cốt liệu này sẽ không yêu cầu bất kỳ thay đổi nào đối với định nghĩa POD. – Casey

1

Tôi không thể chắc chắn điều gì đã xảy ra trong suy nghĩ của ủy ban khi họ thêm hạn chế đó vào định nghĩa tập hợp. Tôi nghi ngờ rằng đó là bởi vì họ cho rằng việc yêu cầu trình biên dịch cũng phải thiết lập một cá thể cho các cuộc gọi hàm ảo (vtable hoặc khác) sẽ khác với các giá trị khởi tạo đơn giản và do đó thêm hạn chế để đơn giản hóa các yêu cầu về trình cài đặt ngôn ngữ.

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