2010-09-13 32 views
16
class Base{ 
    public: 
     void counter(); 
    .... 
} 

class Dervied: public Base{ 
    public: 
     .... 
} 

void main() 
{ 
    Base *ptr=new Derived; 
    ptr->counter(); 
} 

Để xác định rằng con trỏ lớp cơ sở trỏ đến lớp dẫn xuất và sử dụng hàm thành viên có nguồn gốc, chúng tôi sử dụng "ảo".một lớp học có thể có các thành viên dữ liệu ảo không?

Tương tự, chúng tôi có thể tạo thành viên dữ liệu có nguồn gốc "ảo" không? (Các thành viên dữ liệu là công khai)

+2

câu hỏi rõ ràng là tại sao * *? cần gì cho nó? có thể có những cách khác để giải quyết vấn đề đó. – Naveen

+1

Bạn (thường) không nên sử dụng các thành viên dữ liệu công khai và thay vào đó hãy truy cập - vì vậy bạn thậm chí không cần phải có điều này. –

+0

hoặc để nói lại điều này một chút: bạn có thể làm gì với các 'thành viên dữ liệu' ảo (các trường) những gì bạn không thể làm với các thành viên dữ liệu không phải ảo? –

Trả lời

23

virtual là một Chức năng specifier ...

Từ tài liệu tiêu chuẩn,

7.1.2 Function specifiers 
Function-specifiers can be used only in function declarations. 
function-specifier: 
inline 
virtual 
explicit 

Vì vậy, có được không có gì gọi là Thành viên dữ liệu ảo.

Hy vọng điều này sẽ giúp ...

+0

Ya .. nó đã giúp. Đã đi qua "http://publib.boulder.ibm.com/infocenter/comphelp/v7v91/index.jsp?topic=/com.ibm.vacpp7a.doc/language/ref/clrc03cplr099.htm" cũng như ... – vandanak

+1

Thế còn thừa kế ảo thì sao? 'class Foo: public virtual Bar' dường như không phải là một khai báo hàm cho tôi ... –

10

Không, nhưng bạn có thể tạo một hàm ảo để trả về một con trỏ đến những gì bạn gọi thành viên dữ liệu ảo

2

Tôi nghĩ là không, nhưng bạn có thể mô phỏng nó bằng cách sử getters ảo và setter có lẽ?

4

Không, trong C++ không có thành viên dữ liệu ảo.

+0

Bạn có thể trả lại yêu cầu không? – doron

+0

https://isocpp.org/wiki/faq/value-vs-ref-semantics#virt-data- đàm phán về dữ liệu ảo –

2

Để xác định rằng con trỏ lớp cơ sở trỏ đến lớp dẫn xuất và sử dụng hàm thành viên có nguồn gốc, chúng tôi sử dụng "ảo".

Điều đó không đúng. Chúng tôi thực hiện các chức năng ảo để cho phép các lớp dẫn xuất cung cấp việc triển khai khác nhau từ những gì cơ sở cung cấp. Nó không được sử dụng để xác định rằng con trỏ lớp cơ sở trỏ đến lớp dẫn xuất.

Tương tự, chúng tôi có thể tạo thành viên dữ liệu có nguồn gốc "ảo" không? (thành viên dữ liệu được công khai)

Chỉ các chức năng thành viên không tĩnh mới có thể là ảo. Các thành viên dữ liệu không thể.

Here's một liên kết với một số thông tin thêm về rằng

+2

"Chúng tôi tạo các chức năng ảo để cho phép các lớp dẫn xuất cung cấp triển khai khác với những gì cơ sở cung cấp". Không hoàn toàn, bạn đã có được điều đó khi bạn tạo một lớp dẫn xuất và viết một hàm có cùng tên với một trong một lớp cha. Những gì 'virtual' làm là cho phép bạn đưa một đối tượng vào một trong các siêu lớp của nó nhưng vẫn sử dụng việc triển khai lớp dẫn xuất cho các hàm ảo. (Nói cách khác, C++ sử dụng công văn tĩnh cho các hàm bình thường và công văn động cho các hàm ảo.) – JAB

2

Không, bởi vì điều đó sẽ phá vỡ đóng gói theo vô số cách bất ngờ. Bất cứ điều gì bạn muốn đạt được đều có thể được thực hiện với các thuộc tính được bảo vệ và/hoặc các chức năng ảo.

Bên cạnh đó, chức năng ảo là phương thức công văn (tức là chọn chức năng sẽ được gọi), thay vì chọn vị trí bộ nhớ tương ứng với thuộc tính thành viên.

+0

Bạn có thể đưa ra một ví dụ hoặc hai nơi đây sẽ là một vấn đề (và đó không phải là vấn đề thừa kế kim cương)? Tôi đã tự hỏi về lý do của quyết định này. –

0

lẽ bạn có thể gặp sự cố trong một cách tương đương:

class VirtualDataMember{ 
    public: 
    ... 
} 

class DerviedDataMember: public VirtualDataMember{ 
    public: 
    ... 
} 

class Base{ 
    public: 
     VirtualDataMember* dataMember; 
     void counter();  
     ... 
} 
Các vấn đề liên quan