VIRTUAL

     

Ở bài xích này, chúng ta sẽ khám phá virtual vào C++. Từ khoá virtual có một số trong những đặc tính khá thú vị mà bạn thích chia sẻ với các bạn qua bài viết ngày hôm nay. Hãy cùng lamaison.com.vn khám phá nhé.

Bạn đang xem: Virtual


1. Virtual vào C++ Là Gì ? công dụng Của Virtual vào C++

Một số tài liệu tất cả viết tính năng của Virtual Function như sau:

“Virtual Function là để khai báo một function ngơi nghỉ class phụ vương (base class) mà kế tiếp các class kế thừa (derived class) hoàn toàn có thể override function đó”

Nhưng ngóng đã, có gì không ổn ở chỗ này, nếu chỉ với để override thôi thì mình hoàn toàn hoàn toàn có thể khai báo function sinh hoạt base class mà không nên virtual thì vẫn được cơ mà. Vậy ko lẽ đồng minh Virtual Function này vô dụng? Để làm rõ vấn đề cũng như hạn chế bi thảm ngủ vì nên đọc quá nhiều chữ, bọn họ thử xét ví dụ nhỏ tuổi sau:

class Buffalo public: void action()printf("I"m eating grass ");;; class YoungBuffalo : public Buffalo void action()printf("I"m typing keyboard ");;;int main() Buffalo *elon = new Buffalo(); YoungBuffalo *andy = new YoungBuffalo(); elon->action(); andy->action();Output đã ra như vậy này:

I"m eating grassI"m typing keyboardNếu chỉ xét cho đây thì cậu virtual chắc sẽ hơi bi ai vì rất nhiều chuyện dường như vẫn ổn mà lại không yêu cầu đến sự có mặt của nó. Vì vậy chúng ta thử xét tiếp 1 ví dụ như khác để gia công chỗ cho virtual toả sáng một chút.

class Buffalo public: void action()printf("I"m eating grass ");;; class YoungBuffalo : public Buffalo public: void action()printf("I"m typing keyboard ");;;int main() Buffalo *elon = new Buffalo(); Buffalo *andy = new YoungBuffalo(); // không giống với thời điểm nãy là YoungBuffalo *andy = new YoungBuffalo(); elon->action(); andy->action();Lần này output đang là như vậy này:

I"m eating grassI"m eating grassĐến đây thì chắc không nhất thiết phải quá tinh mắt chúng ta cũng đã nhận ra vụ việc rồi đúng không. Tuy nhiên andy được tạo ra từ constructor của class YoungBuffalo thế nhưng nó hành xử lại như thể nó là một Buffalo. Mặc dù vậy ví dụ này trông hơi bị thiếu hụt thông minh vì chả mấy ai khai báo Buffalo *andy = new YoungBuffalo(); như này nhằm tự làm cực nhọc mình cả. Mình vẫn xét một ví dụ thực tiễn hơn chút nữa.

class Buffalo public: void action()printf("I"m eating grass ");;; class YoungBuffalo : public Buffalo public: void action()printf("I"m typing keyboard ");;;void takeAnBuffalo(Buffalo* buffalo) buffalo->action();int main() Buffalo *elon = new Buffalo(); Buffalo *andy = new YoungBuffalo(); takeAnBuffalo(elon); takeAnBuffalo(andy);Output vẫn vẫn lại là:

I"m eating grassI"m eating grassLúc này thì vụ việc thực sự đang rõ rồi, bởi vậy bọn họ sẽ fix với vụ việc này với virtual như sau:

class Buffalo public: virtual void action()printf("I"m eating grass ");; // thêm virtual vào khu vực này; class YoungBuffalo : public Buffalo public: void action()printf("I"m typing keyboard ");;;void takeAnBuffalo(Buffalo* buffalo) buffalo->action();int main() Buffalo *elon = new Buffalo(); Buffalo *andy = new YoungBuffalo(); takeAnBuffalo(elon); takeAnBuffalo(andy);Output:

I"m eating grassI"m typing keyboard

*
Virtual trong C++ Là Gì ? chức năng Của Virtual trong C++

2. Pure Virtual Function vào C++ Là Gì

Hàm thuần ảo (pure virtual function) được thực hiện khi:

Không cần thực hiện hàm này vào lớp cơ sở, chỉ giao hàng cho lớp dẫn xuấtLớp dẫn xuất bắt buộc phải định nghĩa lại hàm thuần ảo

Ví dụ, chúng ta có 1 lớp đại lý là Shape. Những lớp dẫn xuất của lớp Shape là Triangle, Square cùng Circle. Bọn họ muốn tính diện tích của những hình này.

Chúng ta hoàn toàn có thể tạo ra một hàm thuần ảo có tên là calculateArea() vào lớp Shape. Các lớp Triangle, Square và Circle đề nghị định nghĩa lại hàm calculateArea() với phương pháp tính diện tích khác nhau cho từng hình.

Hàm thuần ảo không tồn tại thân hàm và yêu cầu phải hoàn thành với “= 0”.

class Shapepublic: // creating a pure virtual function virtual void calculateArea() = 0;;Lưu ý: Cú pháp “= 0” không phải là gán hàm thuần ảo có mức giá trị bằng 0. Nó chỉ nên cú pháp cho biết đó là hàm thuần ảo (pure virtual function).

*
Pure Virtual Function vào C++ Là Gì

3. Virtual Destructor vào C++

Trong một lớp thì Destructor có thể được lưu lại làm hàm ảo còn Constructor thì không được lưu lại là hàm ảo.

virtual Product(); // illegalvirtual ~Product(); // legalXét một vài ví dụ để gia công rõ Virtual Destructor. đưa sử bao gồm lớp phụ thân Base cùng một lớp nhỏ Derived được lúc này như dưới đây.

Xem thêm: Iphone 7 Màu Nào Đẹp Nhất, Chọn Mua Màu Nào Phù Hợp, Góc Tranh Luận

Trường vừa lòng 1: cách thức lớp phụ thân không đánh dấu Virtual

Phương thức hủy lớp cha không được ghi lại là hàm ảo:

class Base{public: Base() ; ~Base() { cout sau khoản thời gian Build và Debug, chỉ gồm dòng “Destructor Base” được xuất ra, tức là chỉ cách tiến hành lớp thân phụ được call nhưng cách làm của lớp con không được gọi. Dẫn đến hoàn toàn có thể gây buộc phải thiếu sót như không thu hồi bộ lưu trữ các cấp phát động của lớp cha hoặc những thủ tục cần triển khai trước khi đối tượng người dùng được thu hồi.

Xét tiếp ví dụ dưới đây, tương tự như lấy ví dụ trên nhưng gồm sửa thay đổi ở lớp Derived

class Basepublic: Base() ; ~Base() cout m_array = new int<1024>; ; ~Derived() cout m_array; ;int main() Base *b = new Derived(); delete b; return 0;Với lớp nhỏ như trên, tuy vậy định nghĩa cách thức để giải phóng m_array nhưng cách tiến hành của lớp bé không được gọi. Tức là chương tình vẫn rò rỉ 1024*4 bytes bộ nhớ.

Trường đúng theo 2: cách thức lớp phụ vương có đánh dấu Virtual

Phương thức lớp thân phụ được lưu lại là thủ tục ảo:

class Base{public: Base() ; virtual ~Base() { cout Bulid và Debug thì lịch trình xuất ra hai mẫu là

Destructor DerivedDestructor BaseNhư vậy phương thức hủy của lớp con được gọi trước tiếp đến mới gọi cách thức hủy lớp thân phụ và các thủ tục quan trọng trước khi hủy các đối tượng người tiêu dùng đã được tiến hành đầy đủ.

*
Virtual Destructor vào C++

4. Nhược Điểm của những Hàm Ảo

Vì phần lớn thời gian các bạn sẽ muốn các hàm của bản thân mình là ảo, vì sao không làm cho cho toàn bộ các hàm trở yêu cầu ảo? Câu trả lời là bởi vì nó không tác dụng – việc xử lý một cuộc điện thoại tư vấn hàm ảo mất quá nhiều thời gian hơn là giải quyết một cuộc gọi thông thường. Hơn nữa, trình biên dịch cũng phải cấp phép một bé trỏ phụ cho từng đối tượng lớp bao gồm một hoặc nhiều hàm ảo.

*
Nhược Điểm của các Hàm Ảo

5. Tại Sao Không nên người ta gọi Các Hàm Ảo Từ những Hàm sinh sản Hoặc Hàm Hủy

Ở đây, các bạn không nên gọi các hàm ảo từ những hàm sản xuất hoặc hàm hủy. Tại sao?

Hãy lưu giữ rằng khi một lớp Derived được tạo, phần Base được tạo trước. Nếu bạn đã điện thoại tư vấn một hàm ảo từ hàm tạo cửa hàng và phần lớp Derived thậm chí không được tạo, thì nó ko thể điện thoại tư vấn hàm của Derived vày không có đối tượng Derived được khởi tạo nên để gọi hàm. Trong C ++, nó sẽ điện thoại tư vấn hàm trong class Base nắm thế.

Một vấn đề giống như tồn tại đến hàm huỷ. Nếu như khách hàng gọi một hàm ảo trong hàm diệt của lớp Cơ sở, nó sẽ luôn gọi hàm của lớp Cơ sở, cũng chính vì phần Derived của lớp đã trở nên hủy.

Quy tắc: Không lúc nào gọi các hàm ảo từ các hàm chế tạo hoặc hàm hủy.

*
Tại Sao Không nên được gọi Các Hàm Ảo Từ những Hàm sinh sản Hoặc Hàm Hủy

6. Tại Sao chúng ta nên Khai Báo Một Hàm bỏ Là Ảo

Giả sử tất cả class Parent và class Child kế thừa từ Parent.

Xem thêm: Cuối Cùng Tôi Cũng Hiểu Chính Niệm Là Gì ? Vì Sao Bạn Cần Chính Niệm?

Ta định nghĩa bé trỏ: Parent * phường = new Child();

Lúc này để tạo thành Child(), thì Parent() phải được tạo nên trước. Khi họ delete p, thì cả 2 đối tượng người dùng này cũng phải được điện thoại tư vấn Destructor. Vậy nếu không khai báo virtual cho hàm Destructor của Parent, thì chỉ Destructor của Parent được gọi, đối tượng người tiêu dùng Child() vẫn còn đấy đó.