Khai báo lớp cơ sở ảo

Một phần của tài liệu Giáo trình lập trình hướng đối tượng (Trang 118 - 121)

Một vấn đề tồn tại là khi nhiều lớp cơ sở đợc kế thừa trực tiếp bởi một lớp dẫn xuất. Để hiểu rõ hơn vấn đề này, xét tình huống các lớp kế thừa theo sơ đồ nh sau:

Hình 5.4.

ở đây, lớp A đợc kế thừa bởi hai lớp B và C. Lớp D kế thừa trực tiếp cả hai lớp B và C. Nh vậy lớp A đợc kế thừa hai lần bởi lớp D: lần thứ nhất nó đợc kế thừa thông qua lớp B, và lần thứ hai đợc kế thừa thông qua lớp C. Bởi vì có hai bản sao của lớp A có trong lớp D nên một tham chiếu đến một thành phần của lớp A sẽ tham chiếu về lớp A đợc kế thừa gián tiếp thông qua lớp B hay tham chiếu về lớp A đợc kế thừa gián tiếp thông qua lớp C? Để giải quyết tính không rõ ràng này, C+ + có một cơ chế mà nhờ đó chỉ có một bản sao của lớp A ở trong lớp D: đó là sử dụng lớp cơ sở ảo.

Trong ví dụ trên, C++ sử dụng từ khóa vitual để khai báo lớp A là ảo trong các lớp B và C theo mẫu nh sau:

clacc B : virtual public A {...};

clacc C : virtual public A {...};

clacc D : public B, public C {...};

Việc chỉ định A là ảo trong các lớp B và C nghĩa là A sẽ chỉ xuất hiện một lần trong lớp D. Khai báo này không ảnh hởng đến các lớp B và C.

Chú ý: Từ khóa virtual có thể đặt trớc hoặc sau từ khóa public, private, protected. Ví dụ 5.13 #include <iostream.h> #include <conio.h> class A { float x,y; public:

void set(float x1, float y1) { x = x1; y = y1; } float getx() { return x; D

}

float gety() { return y; }

};

class B : virtual public A { };

class C : virtual public A { };

class D : public B, public C { }; void main() { clrscr(); D d; cout<<"\nd.B::set(2,3)\n"; d.B::set(2,3); cout<<"\nd.C::getx() = "; cout<<d.C::getx()<<endl; cout<<"\nd.B::getx() = "; cout<<d.B::getx()<<endl; cout<<"\nd.C::gety() = "; cout<<d.C::gety()<<endl; cout<<"\nd.B::gety() = "; cout<<d.B::gety()<<endl; cout<<"\nd.C::set(2,3)\n"; d.C::set(2,3); cout<<"\nd.C::getx() = "; cout<<d.C::getx()<<endl; cout<<"\nd.B::getx() = "; cout<<d.B::getx()<<endl; cout<<"\nd.C::gety() = "; cout<<d.C::gety()<<endl; cout<<"\nd.B::gety() = "; cout<<d.B::gety()<<endl; getch(); }

Chơng trình trên sẽ cho kết quả: d.B::set(2,3)

d.C::getx() = 2 d.B::getx() = 2 d.C::gety() = 3 d.B::gety() = 3

d.C::set(2,3) d.C::getx() = 2 d.B::getx() = 2 d.C::gety() = 3 d.B::gety() = 3

Một phần của tài liệu Giáo trình lập trình hướng đối tượng (Trang 118 - 121)