2009-08-14 40 views
16

Trong C++, phí trên (bộ nhớ/cpu) kết hợp với kế thừa lớp cơ sở không có chức năng ảo là gì? Nó tốt như một bản sao thẳng + dán của các thành viên lớp học?Overhead của kế thừa C++ không có chức năng ảo

class a 
{ 
public: 
    void get(); 
protected: 
    int _px; 
} 

class b : public a 
{ 

} 

so với

class a 
{ 
public: 
    void get(); 
protected: 
    int _px; 
} 

class b 
{ 
public: 
    void get(); 
protected: 
    int _px; 

} 
+5

Điểm quan trọng trong việc sử dụng thừa kế (công khai) nếu bạn không có chức năng ảo? Bạn sẽ cần ít nhất một destructor ảo. –

+8

@Neil có thể dùng để tái sử dụng mã, tránh tái chế bánh xe – vehomzzz

+5

Trong trường hợp đó, anh ta nên sử dụng bố cục, kế thừa riêng hoặc các chức năng miễn phí. –

Trả lời

23

Có thể một thể nhẹ bộ nhớ trên không (do đệm) khi sử dụng thừa kế so với sao chép và quá khứ, hãy xem xét các định nghĩa lớp sau đây:

struct A 
{ 
    int i; 
    char c1; 
}; 

struct B1 : A 
{ 
    char c2; 
}; 


struct B2 
{ 
    int i; 
    char c1; 
    char c2; 
}; 

sizeof (B1) có thể sẽ là 12, trong khi sizeof (B2) có thể chỉ là 8. Điều này là do lớp cơ sở A được đệm riêng biệt đến 8 byte và sau đó B1 được đệm lại thành 12 byte.

+0

Ah quan sát tốt đẹp. – jameszhao00

+0

Tất cả các câu trả lời khác đều hợp lệ, nhưng đây là điều mà tôi không biết/nghĩ đến trước đây. – jameszhao00

1

Không thực sự, nó chỉ làm tăng bộ nhớ bằng các lớp cơ sở. Bạn có thể đọc thêm trong here trong C++ Câu hỏi thường gặp

+0

Tôi biết rằng có một chi phí bảng chức năng ngay sau khi các chức năng ảo được giới thiệu. Tôi tự hỏi làm thế nào trình biên dịch C++ xử lý kế thừa không có đa hình. – jameszhao00

+0

cho một, nó không cấp phát bộ nhớ cho vtable, không tạo ra một vpointer trong lớp cơ sở, do đó cả trình biên dịch và thời gian chạy mất ít hơn với hàm ảo/dtors. Bạn đang cố gắng để thực hiện? – vehomzzz

14

Sẽ mất nhiều thời gian hơn để biên dịch và sẽ không có thêm thời gian chạy bổ sung. Từ quan điểm của trình tối ưu hóa, các phương thức không phải ảo cũng giống như các thủ tục - chúng có thể được gọi chỉ bằng cách sử dụng địa chỉ bộ nhớ của chúng, mà không phải trả phí từ một bảng phương thức ảo.

+0

Tại sao phải mất nhiều thời gian để biên dịch? chỉ tò mò thôi. Tôi nghĩ rằng trình biên dịch đã đủ thông minh trong những ngày này :) – vehomzzz

+6

Thời gian tăng lên sẽ chỉ là một vài phần nghìn giây, vì trình biên dịch sẽ phải xây dựng cây thừa kế. Nó không đáng quan tâm. –

+0

Bạn không có nghĩa là "giống như phương pháp không kế thừa"? – einpoklum

3

Nếu bạn quên thừa kế ảo, việc có lớp cơ sở là tương đương, bộ nhớ và hiệu suất khôn ngoan, để có thành viên của cùng một lớp. Ngoại trừ việc nó đôi khi có thể tốt hơn (ví dụ một lớp trống có kích thước ít nhất một nhưng có một lớp cơ sở trống có thể thường không có phí).

2

Nếu bạn có thể có con trỏ kiểu Base * trỏ đến đối tượng kiểu Derived *, bạn có thể cần một trình phá hủy ảo và tiền đề ban đầu của bạn không còn áp dụng nữa. Nếu lớp dẫn xuất có một destructor rỗng, và nó không có thành viên hoặc tất cả chúng đều là POD, bạn có thể thoát khỏi mà không có một destructor ảo, nhưng tốt hơn là chơi nó an toàn và làm cho nó ảo ngay từ đầu.

Trình biên dịch sẽ tạo cuộc gọi trực tiếp tới mã thực hiện từng chức năng thành viên không phải ảo, do đó không có phí.

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