2011-07-06 19 views

Trả lời

14

Máy móc cho cuộc gọi ảo (thường là một bảng v, nhưng không cần phải) được thiết lập trong khi ctor-initializer, sau khi xây dựng các subobject cơ sở và trước khi xây dựng các thành viên. Mục [class.base.init] nghị định:

Chức năng thành viên (bao gồm chức năng thành viên ảo, 10.3) có thể được gọi cho đối tượng đang được xây dựng. Tương tự, đối tượng đang được xây dựng có thể là toán hạng của toán tử typeid (5.2.8) hoặc của một số dynamic_cast (5.2.7). Tuy nhiên, nếu các hoạt động này được thực hiện bằng ctor-initializer (hoặc trong một chức năng được gọi trực tiếp hoặc gián tiếp từ ctor-initializer) trước khi tất cả bộ khởi tạo mem cho các lớp cơ sở đã hoàn thành, kết quả của hoạt động không định nghĩa được.

Thực ra, trong khi xây dựng các lớp con cơ sở, máy móc chức năng ảo tồn tại nhưng được thiết lập cho lớp cơ sở. Phần [class.cdtor] nói:

Chức năng của thành viên, bao gồm chức năng ảo (10.3), có thể được gọi trong khi xây dựng hoặc phá hủy (12.6.2). Khi một hàm ảo được gọi trực tiếp hoặc gián tiếp từ một hàm tạo hoặc từ một destructor, bao gồm trong quá trình xây dựng hoặc hủy các thành phần dữ liệu không tĩnh của lớp và đối tượng mà cuộc gọi được áp dụng là đối tượng (gọi nó là x) hoặc sự hủy diệt, hàm được gọi là người ghi đè cuối cùng trong lớp của hàm tạo hoặc hàm hủy và không phải là một hàm ghi đè nó trong một lớp có nguồn gốc cao hơn. Nếu cuộc gọi hàm ảo sử dụng truy cập thành viên lớp rõ ràng (5.2.5) và biểu thức đối tượng đề cập đến đối tượng hoàn chỉnh của x hoặc một trong các lớp con cơ sở của đối tượng đó nhưng không phải là x hoặc một trong các lớp con cơ sở của nó, hành vi là không xác định .

+0

Doe Điều này có nghĩa là 'vptr' sẽ được sửa đổi mỗi khi các subobject cơ bản được xây dựng, nếu có nhiều cấp đạo hàm? – fengqi

2

nó khởi tạo giữa các nhà thầu của cơ sở và các lớp thừa kế:

class Base { Base() { } virtual void f(); }; 
class Derived { Derived(); virtual void f(); }; 

Nó xảy ra khi bộ nhớ thô được chuyển đổi sang đối tượng Base. Điều này xảy ra khi đối tượng Base được chuyển đổi thành đối tượng Derived trong khi xây dựng một đối tượng. Tương tự như vậy xảy ra ngược lại khi phá hủy đối tượng. I E. mỗi khi loại thay đổi, con trỏ vtable được thay đổi. (Tôi chắc rằng một người nào đó nhận xét rằng vtables không cần phải tồn tại theo tiêu chuẩn ..)

0

This msdn article explains it in great detali

Có nó nói:

"Và câu trả lời cuối cùng là ... như bạn mong muốn Nó xảy ra trong các nhà xây dựng.."

vì vậy ..
A :: A(): i (0), j (0)
{
- >> tại đây!
// ...
//
}

Nhưng hãy cẩn thận, chúng ta hãy nói rằng bạn có lớp A, và một lớp A1 có nguồn gốc từ A.

  • Nếu bạn tạo một A mới đối tượng, vptr sẽ được thiết lập ngay từ đầu của các nhà xây dựng của lớp A
  • Nhưng nếu bạn đã tạo ra một đối tượng A1 mới:

"Đây là toàn bộ chuỗi các sự kiện khi bạn xây dựng một thể hiện của lớp A1:

  1. A1 :: A1 gọi A :: Một
  2. A :: Một bộ vtable đến A của vtable
  3. A: : Một thực thi và trả về
  4. A1 :: A1 bộ vtable để vtable
  5. thực thi và trả về
  6. A1 :: A1 A1 của "
+1

Trích dẫn tiêu chuẩn đầu tiên tôi đưa ra trong câu trả lời của tôi cho thấy rằng lời giải thích của bạn không hoàn toàn đúng. Khi bạn thêm câu trả lời trễ, bạn nên đọc và hiểu các câu trả lời hiện có, chỉ trong trường hợp. –

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