LËp tr×nh h­íng ®èi t­îng víi C++ So¹n bëi bé m n c ng nghÖ phÇn mÒm



tải về 0.54 Mb.
trang3/3
Chuyển đổi dữ liệu26.03.2018
Kích0.54 Mb.
#36670
1   2   3

Chuoi p = hello


Chuoi moi
Trong hàm main(), câu lệnh sau:
p = s1;
gán cho con trỏ kiểu ký tự p đối tượng s1. Khi trình biên dịch thấy vế phải của phép gán là đối tượng và vế trái là con trỏ ký tự thì nó sử dụng hàm chuyển kiểu.

s1 = n;


lệnh này trình biên dịch tự động gọi hàm khởi tạo có một tham số, nếu hàm khởi tạo không được định nghĩa thì trình biên dịch sẽ báo lỗi.

Bµi tËp lµm thªm


Xây dựng lớp “ngày” có cài đặt các toán tử ++, -- để tăng lên, giảm xuống 1 ngày.

Bµi thùc hµnh:

BÀI THỰC HÀNH SỐ 5

Môc tiªu:

- Đơn kế thừa

- Đa kế thừa.

BÀI TẬP THỰC HÀNH

5.1 Đơn kế thừa (kế thừa đơn)



5.1 Đơn kế thừa (kế thừa đơn)

Chúng ta sử dụng kế thừa trong lập trình hướng đối tượng để có thể sử dụng lại các chức năng của các lớp khác. Các thành phần của lớp dẫn xuất chỉ có thể truy xuất đến các thành phần của lớp cơ sở có khai báo là publicprotected.




  1. Tạo file mới

  2. Gõ đoạn chương trình sau

#include

#include

class vehicle

{

protected:



int wheels;

double weight;

public:

void initialise(int whls, double wght);

int get_wheels()

{

return wheels;

}

double get_weight()

{

return weight;

}

double wheel_loading()

{

return weight/wheels;

}

};
class car: public vehicle



{

private:

int passenger_load;

public:

void initialise(int whls, double wght, int people = 4);

int passengers()

{

return passenger_load;

}

};
class truck: public vehicle



{

private:

int passenger_load;

double payload;

public:

void init_truck(int number = 2, double max_load = 24000.0);

double efficiency();

int passengers()

{

return passenger_load;

}

};
//initialise to any data desired



void vehicle::initialise(int whls, double wght)

{

wheels = whls;



weight = wght;

}
void car:: initialise(int whls, double wght, int people)

{

passenger_load = people;



wheels = whls;

weight = wght;

}
void truck:: init_truck(int number, double max_load)

{

passenger_load = number;



payload = max_load;

}
double truck::efficiency()

{

return payload/(payload + weight);

}
void main()

{

clrscr();



vehicle bicycle;

bicycle.initialise(2,25);

cout << “Xe dap co “<

cout << “Khoi dong banh xe ”<< bicycle.wheel_loading()



<< “don vi khoi luong tren mot banh xe. \n”;

cout<<”Khoi luong cua xe la ”<

<<”don vi khoi luong. \n\n”;
car c;

c.initialise(4,1500.0,5);

cout<<”Chiec xe o to cho duoc “<

cout<<”Chiec xe o to nang “<

<<”don vi khoi luong.\n”;

cout<<”Khoi dong banh xe “<

<< “don vi khoi luong tren mot banh xe. \n\n”;
truck v;

v.initialise(18,7000.0);

v.init_truck(1,15000.0);

cout<<”Xe tai nang “<

cout<<”Su hieu qua cua xe: ”<< 100.0*v.efficiency()

<<” phan tram.\n”;

}


  1. Lưu file với tên “single51.cpp”

  2. Dịch và chạy chương trình

Kết quả trên màn hình là (nhấn tổ hợp phím Alt F5 để xem) :
Xe dap co 2 banh xe.

Khoi dong banh xe 12.5 don vi khoi luong tren mot banh xe.

Khoi luong cua xe la 25 don vi khoi luong.
Chiec xe o to cho duoc 5 hanh khach.

Chiec xe o to nang 1500 don vi khoi luong.

Khoi dong banh xe 375 don vi khoi luong tren mot banh xe.
Xe tai nang 7000 don vi khoi luong.

Su hieu qua cua xe: 68.181818 phan tram




  1. Đóng file “danag411.cpp”

Trong chương trình trên lớp vehicle có hai thành phần dữ liệu có khai báo là protected, và nhiều hàm có khai báo là public. Lớp vehicle là lớp cơ sở của hai lớp car và truck. Chúng ta thấy trong hai lớp này có truy xuất đến lớp cơ sở.




    1. Đa kế thừa.

Đa kế thừa được sử dụng khi một lớp muốn kế thừa từ nhiều lớp cơ sở.




  1. Tạo file mới

  2. Gõ đoạn chương trình sau

#include

#include

#include


class person_data //one base class

{

private:

char name[25];

int roll_no;

char sex;



public:

void getinfo();

void display();

};
class academics //second base class

{

private:

char course_name[25];



int semester;

char grade[3];



public:

void getinfo();

void display();

};
class stud_scholarship: public person_data, public academics

{

private:

float amount;



public:

void getinfo();

void display();

};
void person_data::getinfo()

{

cout << “Ten: “;



cin>> name;

cout<<”So: “;

cin>>roll_no;

cout<<”Gioi tinh(F/M) : “;

cin>> sex;

}
void person_data:: display()

{

cout<

cout<

cout<

}
void academics::getinfo()

{

cout<<”Ten khoa (BA/MBA/MCA etc)? “;



cin>>course_name;

cout<< “Hoc ky (1/2/3/...)? “;

cin>>semester;

cout<<”muc do (A,B,B+,B-..) ? ”;

cin>>grade;

}
void academics::display()

{

cout<

cout<

cout<

}
void stud_scholarship::getinfo()

{

person_data::getinfo();



academics::getinfo();

cout<<”Su ho tro “;

cin>>amount;

}

void stud_scholarship::display()

{

person_data::display();



academics::display();

cout<

cout<}
void main()

{

clrscr();



stud_scholarship obj;

cout<<”Nhap cac thong tin sau: “<

obj.getinfo();

cout<

cout<<”Ten So Gioi tinh Khoa Hoc ky Muc do”; cout<<”Amount”<

obj.display();

}


  1. Lưu file với tên “multi52.cpp”

  2. Dịch và chạy chương trình

  3. Đóng file “danag411.cpp”

Trong chương trình trên, các lớp cơ sở có hàm trùng tên vì vậy khi lớp dẫn xuất gọi các hàm này phải chỉ rõ là hàm dược gọi của lớp nào (xem hàm getinfo và hàm display của lớp dẫn xuất).


    1. Hàm khởi tạo trong kế thừa

Khi trong lớp cơ sở và lớp dẫn xuất có hàm khởi tạo (constructors) thì lớp cơ sở sẽ được khởi tạo trước với hàm khởi tạo mặc định hoặc hàm có tham số tùy thuộc vào khai báo ở trong lớp dẫn xuất.


  1. Tạo file mới

  2. Gõ đoạn chương trình sau

#include

#include

class Alpha

{

public:

Alpha()

{

cout<< “Ham khoi tao cua lop Alpha”<

}

};
class Beta:public Alpha

{

public:

Beta():Alpha()

{

cout<< “Ham khoi tao cua lop Beta, ke thua tu lop Alpha” <

}

};
class Gamma: public Alpha

{

public:

Gamma():Alpha()

{

cout<< “Ham khoi tao lop Gamma, ke thua thu lop Alpha”



<

}

};



class Delta: public Gamma, public Beta

{

Beta b; //base class object



public:

Delta():Gamma(),Beta()

{

cout<< “Ham khoi tao lop Delta, ke thua thu lop Beta ”



<< “va lop Gamma, \n”

<< “co mot doi tuong Beta o trong “

<

}

};


void main()

{

clrscr();



cout<<”Khai bao mot doi tuong cua lop Alpha \n”;

Alpha aa;

cout<cout<<”Khai bao mot doi tuong cua lop Beta \n”;

Beta bb;


cout<cout<<”Khai bao mot doi tuong cua lop Gamma \n”;

Gamma cc;

cout<
cout<<”Khai bao mot doi tuong cua lop Delta \n”;

Delta dd;

cout<

}


  1. Lưu file với tên “multi53.cpp”

  2. Dịch và chạy chương trình

Màn hình kết quả như sau:
Khai bao mot doi tuong cua lop Alpha

Ham khoi tao cua lop Alpha


Khai bao mot doi tuong cua lop Beta

Ham khoi tao cua lop Alpha

Ham khoi tao cua lop Beta, ke thua tu lop Alpha
Khai bao mot doi tuong cua lop Gamma

Ham khoi tao cua lop Alpha

Ham khoi tao lop Gamma, ke thua thu lop Alpha
Khai bao mot doi tuong cua lop Delta

Ham khoi tao cua lop Alpha

Ham khoi tao lop Gamma, ke thua thu lop Alpha

Ham khoi tao cua lop Alpha

Ham khoi tao cua lop Beta, ke thua tu lop Alpha

Ham khoi tao cua lop Alpha

Ham khoi tao cua lop Beta, ke thua tu lop Alpha

Ham khoi tao lop Delta, ke thua thu lop Beta va lop Gamma,

co mot doi tuong Beta o trong


  1. Đóng file “danag411.cpp”

Trong chương trình trên các bạn sẽ thấy được thứ tự các hàm khởi tạo được gọi như thế nào.

Bµi thùc hµnh:

BÀI THỰC HÀNH SỐ 6

Môc tiªu:

+ Thực hành cách viết chương trình có sử dụng cơ chế đa hình(polymorphism).

+ Làm rõ các khái niệm: hàm ảo, hàm thuần ảo, và hàm hủy ảo (Virtual destructor).

BÀI TẬP THỰC HÀNH

6.1 Cơ chế đa hình (Polymorphism).

6.2 Hàm ảo (Virtual functions).

6.3 Hàm thuần ảo.

6.4 Hàm hủy ảo(Virtual destructors).

6.1 Cơ chế đa hình (Polymorphism).

Cơ chế đa hình trong C++ là cơ chế cho phép hành vi đối tượng có thể có nhiều thể hiện khác nhau tùy thuộc vào lớp thực chất mà đối tượng đó thuộc về. Khả năng cho phép một chương trình sau khi đã biên dịch có thể có nhiều diễn biến xảy ra là một trong những thể hiện của tính đa hình – tính muôn màu muôn vẻ – của chương trình hướng đối tượng, một thông điệp được gởi đi (gởi đến đối tượng) mà không cần biết đối tượng nhận thuộc lớp nào. Để thực hiện được tính đa hình, các nhà thiết kế C++ cho chúng ta dùng cơ chế kết nối động (dynamic binding) thay cho cơ chế kết nối tĩnh (static binding) ngay khi chương trình biên dịch được dùng trong các ngôn ngữ cổ điển như C, Pascal,



6.2 Hàm ảo (Virtual functions).

Hàm ảo là hàm phải được mô tả trong lớp cơ bản, Trước hàm ảo phải có từ khoá virtual. Ta xét ví dụ sau:




#include

#include

#include

class person

{

protected:



char *name;

public:

person(char *n) { name = n;}



virtual void print() // hàm ảo

{

cout << “My name is :”<

}

};

class foreigner : public person

{

public:

foreigner(char *n) : person(n) { }



void printf()

{

cout <
}

};

class alien : public person

{

public:

alien(char *n) :person(n){ }



void print()

{

cout <<”&*^*&%& **^@<

cout << sorry, there’s a communication problem”;

}
};



void main()

{

clrscr();



person* p1;

person *p2;

p1 = new person(“Jack”);

p2 = new foreigner(“Maria”);

cout <<”Introducing a Person:” <

p1->print();

cout <<”Introducing a Foreigner:” <

p2->print();

p1 = new foreigner(“Al Pacino”);

cout << “Reintroducing the Person:” << endln;

p1 ->print();

person* p3;

p3 = new alien(“Martian”);

cout << “Introducing a alien:” << endln;

p3 ->print();
}


Kết quả sau khi chạy chương trình:

Introducing the Person:

My name is Jack

Introducing the Foreiger:

ll mi o nome a Maria

Reintroducing the person:

ll mio nome e Al Pacino

Introducing the alien:

&*^*&%& **^@ Martian

Sorry there’s a communication problem
Trong ví dụ trên ta thấy cả hai lớp dẫn xuất đều có hàm print như trong lớp cơ bản của chúng, hàm print trong lớp person là một hàm ảo. Ban đầu cả hai con trỏ p1 và p2, p3 đếu có kiểu person nhưng sau đó p1 lại thực sự trỏ đến một đối tượng kiểu person trong khi p2 lại trỏ đến một đối tượng kiểu foreigner và p3 trỏ đến đối tượng kiểu alien. Khi thực hiện p2 không gọi hàm print của lớp person mà gọi hàm print của lớp foreigner , và p3 gọi hàm print của lớp alien. Đây chính là cơ chế đa hình mà ta đã nói ở trên.

6.3 Hàm thuần ảo.

Hàm thuần ảo là hàm ảo được mô tả bằng cách gán giá trị 0 cho hàm. Một lớp được gọi là lớp trừu tượng nếu trong lớp tồn tại một hàm ảo và không thể dùng lớp này để định nghĩa một đối tượng.

Xét chương trình sau:



#include

#include


class format

{

public;



void display_form();

virtual void header()

{

cout << this is a header\n”;



}

virtual void body() = 0; // hàm thuần ảo

virtual void footer()

{

cout << “this is a footer\n\n”;



}

}

void Format :: display_form()

{

header();



for( int index = 0;index <3 ; index ++)

{

body();



}

footer();


}
class MyForm : public Format

{

public:



void body() { cout << “This is the new body of text\n”;}

void footer(){ cout << This is the new footer\n”;}

};

void main()

{

clrscr();



Format* first_form = new MyForm;

First_form->display_form();

}



6.4 Hàm hủy ảo(Virtual destructors).

Hàm hủy là hàm được gọi một cách tự động để thực hiện một số công việc nào đó mà người lập trình cần khi đối tượng bị hủy , chẳng hạn hàm hủy dùng để giải phóng bộ nhớ một cách tự động khi đối tượng bị hủy. Tuy nhiên bình thường thì hàm hủy của lớp dẫn xuất sẽ không được gọi mà chỉ có hàm hủy của lớp cơ bản được gọi , nên trong một số trường hợp ta không thể dùng hàm ảo trong một lớp dẫn xuất để thực hiện các thao tác mà ta cần khi một làm khi một đối tượng của lớp mày bị hủy. Vấn đền này được giải quyết bằng cách dúng hàm hủy ảo. Hàm hủy của lớp cơ bản sẽ là một hàm ảo, các lớp dẫn xuất sẽ có hàm hủy riêng và khi đối tượng bị hủy ,hàm hủy của lớp cơ bản và lớp dẫn xuất đều sẽ được gọi.

Xét ví dụ sau;

#include



class Base

{

public:

~Base()

{

cout<<"~Base"<

}

};

class Derived:public Base

{

public:

~Derived()

{

cout<<"~Derived"<

}

};

int main()

{

Base *B;


B = new Derived;

delete B;



return 0;

}

Kết quả khi thực hiện :


~Base

Như vậy ta thấy chỉ có hàm hủy của lớp cơ bản được gọi , còn hàm hủy của lớp dẫn xuất không được gọi .


Bây giờ ta sửa lại chương trình trên như sau:

#include



class Base

{

public:



virtual ~Base()

{

cout<<"~Base"<

}

};

class Derived:public Base

{

public:

virtual ~Derived()

{

cout<<"~Derived"<

}

};

int main()

{

Base *B;


B = new Derived;

delete B;



return 0;

}
Khi đó kết quả của chương trình sẽ là ;

~ Base

~Derived


Bµi tËp lµm thªm

Xây dựng các lớp theo sơ đồ sau đây :



Trong đó HINH là lớp cơ bản, H_TRON, H_CHUNHAT là các lớp dẩn xuất, lớp hình có các hàm ảo thuần ảo



virtual void Ve() // hàm vẽ hình ra màn hình

virtual int TinhDienTich() // hàm tính diện tích

Các lớp dẫn xuất sẽ viết lại các hàm trên để vẽ hay tính diện tích cho thích hợp.




Trang


tải về 0.54 Mb.

Chia sẻ với bạn bè của bạn:
1   2   3




Cơ sở dữ liệu được bảo vệ bởi bản quyền ©hocday.com 2024
được sử dụng cho việc quản lý

    Quê hương