Diễn Đàn Teen Việt -Thế Giới 9x pro
Bạn có muốn phản ứng với tin nhắn này? Vui lòng đăng ký diễn đàn trong một vài cú nhấp chuột hoặc đăng nhập để tiếp tục.

giáo trình ngôn ngữ lập trinh C ++ <phần 6>

Go down

giáo trình ngôn ngữ lập trinh C ++ <phần 6> Empty giáo trình ngôn ngữ lập trinh C ++ <phần 6>

Bài gửi by luongbv93 25th November 2011, 09:46

CHƯƠNG 5

LỚP

Nội dung chương này tập trung trình bày các vấn đề liên quan đến lớp đối tượng trong C++:

• Khái niệm, khai báo và sử dụng lớp

• Khai báo và sử dụng các thành phần của lớp: các thuộc tính và các phương thức của lớp

• Phạm vi truy nhập lớp

• Khai báo và sử dụng các phương thức khởi tạo và huỷ bỏ của lớp

• Sử dụng lớp thông qua con trỏđối tượng, mảng các đối tượng.

5.1 KHÁI NIỆM LỚP ĐỐI TƯỢNG

C++ coi lớp là sự trừu tượng hóa các đối tượng, là một khuôn mẫu để biểu diễn các đối tượng
thông qua các thuộc tính và các hành động đặc trưng của đối tượng.

5.1.1 Định nghĩa lớp đối tượng

Đểđịnh nghĩa một lớp trong C++, ta dùng từ khóa class với cú pháp:

class <Tên lớp>{

};

Trong đó:

• class: là tên từ khóa bắt buộc đểđịnh nghĩa một lớp đối tượng trong C++.

• Tên lớp: do người dùng tựđịnh nghĩa. Tên lớp có tính chất như tên kiểu dữ liệu để sử
dụng sau này. Cách đặt tên lớp phải tuân thủ theo quy tắc đặt tên biến trong C++.

Ví dụ:

class Car{

};

là định nghĩa một lớp xe ô tô (Car). Lớp này chưa có bất kì một thành phần nào, việc định nghĩa
các thành phần cho lớp sẽđược trình bày trong mục 5.2.

Lưu ý:

• Từ khóa class là bắt buộc đểđịnh nghĩa một lớp đối tượng trong C++. Hơn nữa, C++ có
phân biệt chữ hoa chữ thường trong khai báo cho nên chữclass phải được viết bằng chữ
thường.

Ví dụ:

class Car{ // Định nghĩa đúng

};

nhưng:

Class Car{ // Lỗi từ khóa

};

• Bắt buộc phải có dấu chấm phẩy “;” ở cuối định nghĩa lớp vì C++ coi định nghĩa một lớp
nhưđịnh nghĩa một kiểu dữ liệu, cho nên phải có dấu chấm phẩy cuối định nghĩa (tương
tựđịnh nghĩa kiểu dữ liệu kiểu cấu trúc).

• Để phân biệt với tên biến thông thường, ta nên (nhưng không bắt buộc) đặt tên lớp b ắt đầu
bằng một chữ in hoa và các tên biến bắt đầu bằng một chữ in thường.

5.1.2 Sử dụng lớp đối tượng

Lớp đối tượng được sử dụng khi ta khai báo các thể hiện của lớp đó. Một thể hiện của một lớp
chính là một đối tượng cụ thể của lớp đó. Việc khai báo một thể hiện của một lớp được thực hiện
như cú pháp khai báo một biến có kiểu lớp:

<Tên lớp> <Tên biến lớp>;

Trong đó:

• Tên lớp: là tên lớp đối tượng đã được định nghĩa trước khi khai báo biến.

• Tên biến lớp: là tên đối tượng cụ thể. Tên biến lớp sẽđược sử dụng như các biến thông
thường trong C++, ngoại trừ việc nó có kiểu lớp đối tượng.

Ví dụ, muốn khai báo một thể hiện (biến) của lớp Car đã được định nghĩa trong mục 5.1.1, ta khai
báo như sau:

Car myCar;

Sau đó, ta có thể sử dụng biến myCar trong chương trình như các biến thông thường: truyền tham
số cho hàm, gán cho biến khác …

Lưu ý:

• Khi khai báo biến lớp, ta không dùng lại từ khóa class nữa. Từ khóa class chỉđược sử
dụng khi định nghĩa lớp mà không dùng khi khai báo biến lớp.

Ví dụ, khai báo:

Car myCar; // đúng

là đúng, nhưng khai báo:

class Car myCar; // Lỗi cú pháp

là sai cú pháp.

5.2 CÁC THÀNH PHẦN CỦA LỚP

Việc khai báo các thành phần của lớp có dạng như sau:

class <Tên lớp>{

private:

<Khai báo các thành phần riêng>

protected:

<Khai báo các thành phần được bảo vệ>

public:

<Khai báo các thành phần công cộng>

};

Trong đó:

• private: là từ khóa chỉ tính chất của C++ để chỉ ra rằng các thành phần được khai báo
trong phạm vi từ khóa này là riêng tưđối với lớp đối tượng. Các đối tượng của các lớp
khác không truy nhập được các thành phần này.

• protected: các thành phần được khai báo trong phạm vi từ khóa này đều được bảo vệ. Qui
định loại đối tượng nào được truy nhập đến các thành phần được bảo vệ sẽđược mô tả chi
tiết trong mục 5.3.

• public: các thành phần công cộng. Các đối tượng của các lớp khác đều có thể truy nhập
đến các thành phần công cộng của một đối tượng bất kì.

Các thành phần của lớp được chia làm hai loại:

• Các thành phần chỉ dữ liệu của lớp, được gọi là thuộc tính của lớp

• Các thành phần chỉ hành động của lớp, được gọi làph ương thức của lớp.

5.2.1 Thuộc tính của lớp

Khai báo thuộc tính

Thuộc tính của lớp là thành phần chứa dữ liệu, đặc trưng cho các tính chất của lớp. Thuộc tính của
lớp được khai báo theo cú pháp sau:

<Kiểu dữ liệu> <Tên thuộc tính>;

Trong đó:

• Kiểu dữ liệu: có thể là các kiểu dữ liệu cơ bản của C++, cũng có thể là các kiểu dữ liệu
phức tạp do người dùng tựđịnh nghĩa như struct, hoặc kiểu là một lớp đã được định nghĩa
trước đó.

• Tên thuộc tính: là tên thuộc tính của lớp, có tính chất như một biến thông thường. Tên
thuộc tính phải tuân theo quy tắc đặt tên biến của C++.

Ví dụ, khai báo:

class Car{

private:

int speed;

public:

char mark[20];

};

là khai báo một lớp xe ô tô (Car), có hai thuộc tính: thuộc tính tốc độ (speed) có tính chất private,
thuộc tính nhãn hiệu xe (mark) có tính chất public.

Lưu ý:

• Không được khởi tạo giá trị ban đầu cho các thuộc tính ngay trong lớp. Vì các thuộc tính
chỉ có giá trị khi nó gắn với một đối tượng cụ thể, là một thể hiện (biến) của lớp.

Ví dụ:

class Car{

private:

int speed; // đúng

int weight = 500; // lỗi

};

• Khả năng truy nhập thuộc tính của lớp là phụ thuộc vào thuộc tính ấy được khai báo trong
phạm vi của từ khóa nào: private, protected hay public.

• Thông thường, do yêu cầu đóng gói dữ liệu của hướng đối tượng, ta nên khai báo các
thuộc tính có tính chất riêng tư (ptivate). Nếu muốn các đối tượng khác truy nhập được
vào các thuộc tính này, ta xây dựng các hàm public truy nhập (get / set) đến thuộc tính đó.

Sử dụng thuộc tính

Thuộc tính có thểđược sử dụng cho các chương trình nằm ngoài lớp thông qua tên biến lớp hoặc
sử dụng ngay trong lớp bởi các phương thức của lớp.

• Nếu thuộc tính được dùng bên ngoài phạm vi lớp, cú pháp phải thông qua tên biến lớp
(cách này chỉ sử dụng được với các biến có tính chất public):

<Tên biến lớp>.<tên thuộc tính>;

• Nếu thuộc tính được dùng bên trong lớp, cú pháp đơn giản hơn:

<Tên thuộc tính>;

Ví dụ, với định nghĩa lớp:

class Car{

private:

int speed;

public:

char mark[20];

};

ta khai báo một biến lớp:

Car myCar;

Thì có thể sử dụng thuộc tính nhãn hiệu xe khi in ra màn hình như sau:

cout << myCar.mark;

Lưu ý:

• Khi dùng thuộc tính bên trong các phương thức của lớp, mà tên thuộc tính lại bị trùng với
tên biến toàn cục (tự do) của chương trình, ta phải chỉ rõ việc dùng tên thuộc tính của lớp
(mà không phải tên biến toàn cục) bằng cách dùng chỉ thị phạm vi lớp “::” với cú pháp:

<Tên lớp>::<Tên thuộc tính>;

5.2.2 Phương thức của lớp

Khai báo khuôn mẫu phương thức

Một phương thức là một thao tác thực hiện một số hành động đặc trưng của lớp đối tượng.
Phương thức được khai báo tương tự như các hàm trong C++:

<Kiểu trả về> <Tên phương thức>([<Các tham số>]);

Trong đó:

• Kiểu trả về: là kiểu dữ liệu trả về của phương thức. Kiểu có thể là các kiểu dữ liệu cơ bản
của C++, cũng có thể là kiểu do người dùng định nghĩa, hoặc kiểu lớp đã được định nghĩa.

• Tên phương thức: do người dùng tựđặt tên, tuân theo quy tắc đặt tên biến của C++.

• Các tham số: Các tham sốđầu vào của phương thức, được biểu diễn bằng kiểu dữ liệu
tương ứng. Các tham sốđược phân cách bởi dấu phẩy “,”. Các tham số là tùy chọn (Phần
trong dấu ngoặc vuông “[ ]” là tùy chọn).

Ví dụ, khai báo:

class Car{

private:

int speed;

char mark[20];

public:

void show();

};

là định nghĩa một lớp Car có hai thuộc tính cục bộ là speed và mark, và khai báo một phương thức
show() để mô tảđối tượng xe tương ứng. Show() là một phương thức không cần tham số và kiểu
trả về là void.

Lưu ý:

• Khả năng truy nhập phương thức từ bên ngoài là phụ thuộc vào phương thức được khai
báo trong phạm vi của từ khóa nào: private, protected hay public.

Định nghĩa phương thức

Trong C++, việc cài đặt chi tiết nội dung của phương thức có thể tiến hành ngay trong phạm vi
lớp hoặc bên ngoài phạm vi định nghĩa lớp. Cú pháp chỉ khác nhau ở dòng khai báo tên phương
thức.

• Nếu cài đặt phương thức ngay trong phạm vi định nghĩa lớp, cú pháp là:

<Kiểu trả về> <Tên phương thức>([<Các tham số>]){

… // Cài đặt chi tiết

}

• Nếu cài đặt phương thức bên ngoài phạm vi định nghĩa lớp, ta phải dùng chỉ thị phạm vi
“::” để chỉ ra rằng đấy là một phương thức của lớp mà không phải là một hàm tự do trong
chương trình:

<Kiểu trả về> <Tên lớp>::<Tên phương thức>([<Các tham số>]){

… // Cài đặt chi tiết

}

Ví dụ, nếu cài đặt phương thức show() của lớp Car ngay trong phạm vi định nghĩa lớp, ta cài đặt
như sau:

class Car{

private:

int speed; // Tốc độ

char mark[20]; // Nhãn hiệu

public:

void show(){ // Khai báo phương thức ngay trong lớp

cout << “This is a ” << mark << “ having a speed of ”



<< speed << “km/h!” << endl;

return;

}

};

Nếu muốn cài đặt bên ngoài lớp, ta cài đặt như sau:

class Car{

private:

int speed; // Tốc độ

char mark[20]; // Nhãn hiệu

public:

void show(); // Giới thiệu xe

};

/* Khai báo phương thức bên ngoài lớp */

void Car::show(){

cout << “This is a ” << mark << “ having a speed of ”

<< speed << “km/h!” << endl;

return;

}

Lưu ý:

• Nếu phương thức được cài đặt ngay trong lớp thì các tham số phải tường minh, nghĩa là
mỗi tham số phải được biểu diễn bằng một cặp <Kiểu dữ liệu> <Tên tham số> như khi cài
đặt chi tiết một hàm tự do trong chương trình.

• Thông thường, chỉ các phương thức ngắn (trên một dòng) là nên cài đặt ngay trong lớp.
Còn lại nên cài đặt các phương thức bên ngoài lớp để chương trình được sáng sủa, rõ ràng
và dễ theo dõi.

Sử dụng phương thức

Cũng tương tự như các thuộc tính của lớp, các phương thức cũng có thểđược sử dụng bên ngoài
lớp thông qua tên biến lớp, hoặc có thểđược dùng ngay trong lớp bởi các phương thức khác của
lớp định nghĩa nó.

• Nếu phương thức được dùng bên ngoài phạm vi lớp, cú pháp phải thông qua tên biến lớp
(cách này chỉ sử dụng được với các phương thức có tính chất public):

<Tên biến lớp>.<Tên phương thức>([<Các đối số>]);

• Nếu thuộc tính được dùng bên trong lớp, cú pháp đơn giản hơn:

<Tên phương thức>([<Các đối số>]);

Ví dụ, với định nghĩa lớp:

class Car{

private:

int speed; // Tốc độ

char mark[20]; // Nhãn hiệu

public:

void show(); // Giới thiệu xe

};

/* Khai báo phương thức bên ngoài lớp */

void Car::show(){

cout << “This is a ” << mark << “ having a speed of ”

<< speed << “km/h!” << endl;

return;

}

ta khai báo một biến lớp:

Car myCar;

Thì có thể sử dụng phương thức giới thiệu xe như sau:

myCar.show();

Lưu ý:

• Khi dùng phương thức bên trong các phương thức khác của lớp, mà phương thức lại bị
trùng với các phương thức tự do của chương trình, ta phải chỉ rõ việc dùng phương thức
của lớp (mà không phải dùng phương thức tự do) bằng cách dùng chỉ thị phạm vi lớp “::”
với cú pháp:

<Tên lớp>::<Tên phương thức>([<Các đối số>]);

Chương trình 5.1 cài đặt đầy đủ một lớp xe ô tô (Car) với các thuộc tính có tính chất cục bộ:

• Tốc độ xe (speed)

• Nhãn hiệu xe (mark)

• Giá xe (price)

Và các phương thức có tính chất public:

• Khởi tạo các tham số (init)

• Giới thiệu xe (show)

• Các phương thức truy nhập (get/set) các thuộc tính

Sau đó, chương trình main sẽ sử dụng lớp Car này đểđịnh nghĩa các đối tượng cụ thể và sử dụng
các phương thức của lớp này.

Chương trình 5.1

#include<stdio.h>

#include<conio.h>

#include<string.h>

/* Định nghĩa lớp */

class Car{

private:

int speed; // Tốc độ

char mark[20]; // Nhãn hiệu

float price; // Giá xe

public:

void setSpeed(int); // Gán tốc độ cho xe

int getSpeed(); // Đọc tốc độ xe

void setMark(char); // Gán nhãn cho xe

char[ ] getMark(); // Đọc nhãn xe

void setPrice(float); // Gán giá cho xe

float getPrice(); // Đọc giá xe

void init(int, char[ ], float);// Khởi tạo thông tin về xe

void show(); // Giới thiệu xe

};

/* Khai báo phương thức bên ngoài lớp */

void Car::setSpeed(int speedIn){ // Gán tốc độ cho xe

speed = speedIn;

}

int Car::getSpeed(){ // Đọc tốc độ xe

return speed;

}

void Car::setMark(char markIn){ // Gán nhãn cho xe

strcpy(mark, markIn);

}

char[] Car::getMark(){ // Đọc nhãn xe

return mark;

}

void Car::setPrice(float priceIn){ // Gán giá cho xe

price = priceIn;

}

float Car::getPrice(){ // Đọc giá xe

return price;

}

void Car::init(int speedIn, char markIn[], float priceIn){

speed = speedIn;

strcpy(mark, markIn);

price = priceIn;

return;

}

void Car::show(){ // Phương thức giới thiệu xe

cout << “This is a ” << mark << “ having a speed of ”

<< speed << “km/h and its price is $” << price << endl;

return;

}

// Hàm main, chương trình chính
void main(){

clrscr();

Car myCar; // Khai báo biến lớp

// Khởi tạo lần thứ nhất

cout << “Xe thu nhat: ” << endl;

myCar.init(100, “Ford”, 3000);

cout << “Toc do (km/h): ” << myCar.getSpeed() << endl;

cout << “Nhan hieu : ” << myCar.getMark() << endl;

cout << “Gia ($): ” << myCar.getPrice() << endl;

// Thay đổi thuộc tính xe

cout << “Xe thu hai: ” << endl;

myCar.setSpeed(150);

myCar.setMark(“Mercedes”);

myCar.setPrice(5000);

myCar.show();

return;

}

Chương trình 5.1 sẽ in ra kết quả như sau:

Xe thu nhat:

Toc do (km/h): 100

Nhan hieu: Ford

Gia ($): 3000

Xe thu hai:

This is a Mercedes having a speed of 150km/h and its price is $5000

5.3 PHẠM VI TRUY NHẬP LỚP

5.3.1 Phạm vi truy nhập lớp

Trong C++, có một số khái niệm về phạm vi, xếp từ bé đến lớn như sau:

• Phạm vi khối lệnh: Trong phạm vi giữa hai dấu giới hạn “{}” của một khối lệnh. Ví dụ
các lệnh trong khối lệnh lặp while(){ } sẽ có cùng phạm vi khối lệnh.

• Phạm vi hàm: Các lệnh trong cùng một hàm có cùng mức phạm vi hàm.

• Phạm vi lớp: Các thành phần của cùng một lớp có cùng phạm vi lớp với nhau: các thuộc
tính và các phương thức của cùng một lớp.

• Phạm vi chương trình (còn gọi là phạm vi tệp): Các lớp, các hàm, các biến được khai
báo và định nghĩa trong cùng một tệp chương trình thì có cùng phạm vi chương trình.
Trong phạm vi truy nhập lớp, ta chỉ quan tâm đến hai phạm vi lớn nhất, đó là phạm vi lớp và
phạm vi chương trình. Trong C++, phạm vi truy nhập lớp được quy định bởi các từ khóa về thuộc
tính truy nhập:

• private: Các thành phần của lớp có thuộc tính private thì chỉ có thểđược truy nhập trong
phạm vi lớp.

• protected: Trong cùng một lớp, thuộc tính protected cũng có ảnh hưởng tương tự như
thuộc tính private: các thành phần lớp có thuộc tính protected chỉ có thểđược truy nhập
trong phạm vi lớp. Ngoài ra nó còn có thểđược truy nhập trong các lớp con khi có kế thừa
(sẽđược trình bày trong chương 6).

• public: các thành phần lớp có thuộc tính public thì có thểđược truy nhập trong phạm vi
chương trình, có nghĩa là nó có thểđược truy nhập trong các hàm tự do, các phương thức
bên trong các lớp khác…

Ví dụ, thuộc tính price của lớp Car có tính chất private nên chỉ có thể truy nhập bởi các phương
thức của lớp Car. Không thể truy nhập từ bên ngoài lớp (phạm vi chương trình), chẳng hạn trong
một hàm tự do ngoài lớp Car.

void Car::setPrice(float priceIn){

price = priceIn; // Đúng, vì setPrice là một phương thức

// của lớp Car

}

nhưng:

void freeFunction(Car myCar){

myCar.price = 3000;// Lỗi, vì freeFunction là một hàm tự do

// nằm ngoài phạm vi lớp Car

}

Khi đó, hàm freeFunction phải truy nhập gián tiếp đến thuộc tính price thông qua phương thức
truy nhập có tính chất public như sau:

void freeFunction(Car myCar){

myCar.setPrice(3000);// Đúng, vì setPrice là một phương thức
của

// lớp Car có thuộc tính public

}

Tuy nhiên, C++ cho phép một cách đặc biệt để truy nhập đến các thành phần private và protected
của một lớp bằng khái niệm hàm bạn và lớp b ạn của một lớp: trong các hàm bạn và lớp bạn của
một lớp, có thể truy nhập đến các thành phần private và protected như bên trong phạm vi lớp đó.

5.3.2 Hàm bạn

Có hai kiểu hàm bạn cơ bản trong C++:

• Một hàm tự do là hàm bạn của một lớp

• Một hàm thành phần (phương thức) của một lớp là bạn của một lớp khác

Ngoài ra còn có một số kiểu hàm bạn mở rộng từ hai kiểu này:

• Một hàm là bạn của nhiều lớp

• Tất cả các hàm của một lớp là bạn của lớp khác (lớp bạn)

Hàm tự do bạn của một lớp

Một hàm bạn của một lớp được khai báo bằng từ khóa friend khi khai báo khuôn mẫu hàm trong
lớp tương ứng.

class <Tên lớp>{

… // Khai báo các thành phần lớp như thông thường

// Khai báo hàm bạn

friend <Kiểu trả về> <Tên hàm bạn>([<Các tham số>]);

};

Khi đó, định nghĩa chi tiết hàm bạn được thực hiện nhưđịnh nghĩa một hàm tự do thông thường:

<Kiểu trả về> <Tên hàm bạn>([<Các tham số>]){

… // Có thể truy nhập trực tiếp các thành phần private

// của lớp đã khai báo

}

Lưu ý:

• Mặc dù hàm bạn được khai báo khuôn mẫu hàm trong phạm vi lớp, nhưng hàm bạn tự do
lại không phải là một phương thức của lớp. Nó là hàm tự do, việc định nghĩa và sử dụng
hàm này hoàn toàn tương tự như các hàm tự do khác.

• Việc khai báo khuôn mẫu hàm bạn trong phạm vi lớp ở vị trí nào cũng được: hàm bạn
không bịảnh hưởng bởi các từ khóa private, protected hay public trong lớp.

• Trong hàm bạn, có thể truy nhập trực tiếp đến các thành phần private và protected của đối
tượng có kiểu lớp mà nó làm bạn (truy nhập thông qua đối tượng cụ thể).

Chương trình 5.2 minh họa việc định nghĩa một hàm bạn của lớp Car, hàm này so sánh xem hai
chiếc xe, chiếc nào đắt hơn.

Chương trình 5.2

#include<stdio.h>

#include<conio.h>

#include<string.h>

/* Định nghĩa lớp */

class Car{

private:

int speed; // Tốc độ

char mark[20]; // Nhãn hiệu

float price; // Giá xe

public:

void init(int, char[ ], float);// Khởi tạo thông tin về xe

// Khai báo hàm bạn của lớp

friend void moreExpensive(Car, Car);

};

/* Khai báo phương thức bên ngoài lớp */

void Car::init(int speedIn, char markIn[], float priceIn){

speed = speedIn;

strcpy(mark, markIn);

price = priceIn;

return;

}

/* Định nghĩa hàm bạn tự do */

void moreExpensive(Car car1, Car car2){

if(car1.price > car2.price)//Truy nhập đến các thuộc tính private

cout << “xe thu nhat dat hon” << endl;

else if(car1.price < car2.price)

cout << “xe thu nhat dat hon” << endl;

else

cout << “hai xe dat nhu nhau” << endl;

return;

}

// Hàm main, chương trình chính

void main(){

clrscr();

Car car1, car2; // Khai báo biến lớp

// Khởi tạo xe thứ nhất, thứ hai

car1.init(100, “Ford”, 3000);

car2.init(150, “Mercedes”, 3500);

// So sánh giá hai xe

moreExpensive(car1, car2); // Sử dụng hàm bạn tự do

return;

}

Chương trình 5.2 sẽ in ra thông báo:

xe thu hai dat hon

vì xe thứ hai có giá $3500, trong khi xe thứ nhất được khởi tạo giá là $3000.

Phương thức lớp là b ạn của một lớp khác

Trong C++, một phương thức của lớp này cũng có thể làm bạn của một lớp kia. Để khai báo một
phương thức f của lớp B là bạn của lớp A và f nhận một tham số có kiểu lớp A, ta phải khai báo
tuần tự như sau (trong cùng một chương trình):

• Khai báo khuôn mẫu lớp A, để làm tham số cho hàm f của lớp B:

class A;

• Khai báo lớp B với hàm f như khai báo các lớp thông thường:

class B{

… // Khai báo các thành phần khác của lớp B

void f(A);

};

• Khai báo chi tiết lớp A với hàm f của lớp B là bạn

class A{

… // Khai báo các thành phần khác của lớp A

friend void B::f(A);

};

• Định nghĩa chi tiết hàm f của lớp B:

void B::f(A){

… // Định nghĩa chi tiết hàm f

}

Lưu ý:

• Trong trường hợp này, hàm f chỉđược định nghĩa chi tiết một khi lớp A đã được định
nghĩa chi tiết. Do vậy, chỉ có thểđịnh nghĩa chi tiết hàm f ngay trong lớp A (ở bước 3)
hoặc sau khi định nghĩa lớp A (ở bước 4), mà không thểđịnh nghĩa chi tiết hàm f ngay
trong lớp B (ở bước 2).

• Hàm f có thể truy nhập đến các thành phần private và protected của cả hai lớp A và B.
Tuy nhiên, muốn f truy nhập đến các thành phần của lớp A thì phải thông qua một đối
tượng cụ thể có kiểu lớp A.

Chương trình 5.3 minh họa việc cài đặt và sử dụng một hàm permission() của lớp Person, là hàm
bạn của lớp Car. Hàm này thực hiện việc kiểm tra xem một người có đủ quyền điều khiển xe hay
không, theo luật sau:

• Với các loại xe thông thường, người điều khiển phải đủ 18 tuổi.

• Với các loại xe có tốc độ cao hơn 150km/h, người điều khiển phải đủ 21 tuổi.

Chương trình 5.3

#include<stdio.h>

#include<conio.h>

#include<string.h>

class Car; // Khai báo nguyên mẫu lớp

/* Định nghĩa lớp Person */

class Person{

private:

char name[25]; // Tên

int age; // Tuổi

public:

void init(char[ ], int); // Khởi tạo thông tin về người

int permission(Car); // Xác định quyền điều khiển xe

};

/* Định nghĩa lớp Car */

class Car{

private:

int speed; // Tốc độ

char mark[20]; // Nhãn hiệu

float price; // Giá xe

public:

void init(int, char[ ], float);// Khởi tạo thông tin về xe

// Khai báo hàm bạn của lớp

friend int Person::permission(Car);

};

/* Khai báo phương thức bên ngoài lớp */

void Person::init(char nameIn[], int ageIn){

strcpy(name, nameIn);

age = ageIn;

return;

}

void Car::init(int speedIn, char markIn[ ], float priceIn){

speed = speedIn;

strcpy(mark, markIn);

price = priceIn;

return;

}

/* Định nghĩa hàm bạn */

int Person::permission(Car car){

if(age < 18)

return 0;

//Truy nhập thuộc tính private thông qua đối tượng car

if((age < 21)&&(car.speed > 150))

return 0;

return 1;

}

// Hàm main, chương trình chính

void main(){
clrscr();

// Khai báo các biến lớp

Car car;

Person person;

// Khởi tạo các đối tượng

car.init(100, “Ford”, 3000);

person.init(“Vinh”, 20);

// Xác định quyền điều khiển xe

if(person.permission(car)) // Sử dụng hàm bạn

cout << “Co quyen dieu khien” << endl;

else

cout << “Khong co quyen dieu khien” << endl;

return;

}

Chương trình 5.3 sẽ hiển thị thông báo:

Co quyen dieu khien

Vì người chủ xe đã 20 tuổi và xe chỉ có tốc độ 100km/h.

5.3.3 Lớp bạn

Khi tất cảc các phương thức của một lớp là bạn của một lớp khác, thì lớp của các phương thức đó
cũng trở thành lớp bạn của lớp kia. Muốn khai báo một lớp B là lớp bạn của lớp A, ta khai báo
theo tuần tự sau:

• Khai báo khuôn mẫu lớp B:

class B;

• Định nghĩa lớp A, với khai báo B là lớp bạn:

class A{

… // Khai báo các thành phần của lớp A

// Khai báo lớp bạn B

friend class B;

};

• Định nghĩa chi tiết lớp B:

class B{

… // Khai báo các thành phần của lớp B

};

Lưu ý:

• Trong trường hợp này, lớp B là lớp bạn của lớp A nhưng không có nghĩa là lớp A cũng là
bạn của lớp B: tất cả các phương thức của lớp B có thể truy nhập các thành phần private
của lớp A (thông qua các đối tượng có kiểu lớp A) nhưng các phương thức của lớp A lại
không thể truy nhập đến các thành phần private của lớp B.
• Muốn các phương thức của lớp A cũng truy nhập được đến các thành phần private của lớp
B, thì phải khai báo thêm là lớp A cũng là lớp bạn của lớp B.

5.4 HÀM KHỞI TẠO VÀ HUỶ BỎ

5.4.1 Hàm khởi tạo

Hàm khởi tạo được gọi mỗi khi khai báo một đối tượng của lớp. Ngay cả khi không được khai báo
tường minh, C++ cũng gọi hàm khởi tạo ngầm định khi đối tượng được khai báo.

Khai báo hàm khởi tạo

Hàm khởi tạo của một lớp được khai báo tường minh theo cú pháp sau:

class <Tên lớp>{

public:

<Tên lớp>([<Các tham số>]); // Khai báo hàm khởi tạo

};

Ví dụ:

class Car{

int speed;

char mark[20];

float price;

public:

Car(int speedIn, char markIn[ ], float priceIn){

speed = speedIn;

strcpy(mark, markIn);

price = priceIn;

}

};

là khai báo một hàm khởi tạo với ba tham số của lớp Car.

Lưu ý:

• Hàm khởi tạo phải có tên trùng với tên của lớp

• Hàm khởi tạo không có giá trị trả về

• Hàm khởi tạo có tính chất public

• Có thể có nhiều hàm khởi tạo của cùng một lớp

Sử dụng hàm khởi tạo của lớp

Hàm khởi tạo được sử dụng khi khai báo biến lớp. Khi đó, ta có thể vừa khai báo, vừa khởi tạo giá
trị các thuộc tính của đối tượng lớp theo cú pháp sau:

<Tên lớp> <Tên đối tượng>([<Các đối số khởi tạo>]);

Trong đó:

• Tên lớp: là tên kiểu lớp đã được định nghĩa

• Tên đối tượng: là tên biến có kiểu lớp, tuân thủ theo quy tắc đặt tên biến của C++
• Các đối số khởi tạo: Là các đối số tương ứng với hàm khởi tạo của lớp tương ứng. Tương
tự như việc truyền đối số khi dùng các lời gọi hàm thông thường.

Ví dụ, nếu lớp Car có hàm khởi tạo Car(int, char[ ], float) thì khi khai báo biến có kiểu lớp Car, ta
có thể sử dụng hàm khởi tạo này như sau:

Car myCar(100, “Ford”, 3000);

Lưu ý:

• Khi sử dụng hàm khởi tạo, phải truyền đúng số lượng và đúng kiểu của các tham số của
các hàm khởi tạo đã được định nghĩa của lớp.

• Khi một lớp đã có ít nhất một hàm khởi tạo tường minh, thì không được sử dụng hàm khởi
tạo ngầm định của C++. Do đó, khi đã khai báo ít nhất một hàm khởi tạo, nếu muốn khai
báo biến mà không cần tham số, lớp tương ứng phải có ít nhất một hàm khởi tạo không có
tham số.

Ví dụ, nếu lớp Car chỉ có duy nhất một hàm khởi tạo như sau:

class Car{

public:

Car(int, char[ ], float);

};

thì không thể khai báo một biến như sau:

Car myCar; // Khai báo lỗi

• Trong trường hợp dùng hàm khởi tạo không có tham số, ta không cần phải sử dụng cặp
dấu ngoặc đơn “()” sau tên biến đối tượng. Việc khai báo trở thành cách khai báo thông
thường.

Chương trình 5.4a minh họa việc định nghĩa và sử dụng lớp Car với hai hàm khởi tạo khác nhau.

Chương trình 5.4a

#include<stdio.h>

#include<conio.h>

#include<string.h>

/* Định nghĩa lớp */

class Car{

private:

int speed; // Tốc độ

char mark[20]; // Nhãn hiệu

float price; // Giá xe

public:

Car(); // Khởi tạo không tham số

Car(int, char[ ], float);// Khởi tạo đầy đủ tham số

void show(); // Giới thiệu xe

};

/* Khai báo phương thức bên ngoài lớp */

Car::Car(){ // Khởi tạo không tham số

speed = 0;

strcpy(mark, “”);

price = 0;

}

// Khởi tạo có đầy đủ tham số

Car::Car(int speedIn, char markIn[], float priceIn){

speed = speedIn;

strcpy(mark, markIn);

price = priceIn;

}

void Car::show(){ // Phương thức giới thiệu xe

cout << “This is a ” << mark << “ having a speed of ”

<< speed << “km/h and its price is $” << price << endl;

return;

}

// Hàm main, chương trình chính

void main(){

clrscr();

Car myCar1; // Sử dụng hàm khởi tạo không tham số

Car myCar2(150, “Mercedes”, 5000);// Dùng hàm khởi tạo đủ tham số

// Giới thiệu xe thứ nhất

cout << “Xe thu nhat: ” << endl;

myCar1.show();

// Giới thiệu xe thứ hai

cout << “Xe thu hai: ” << endl;

myCar2.show();

return;

}

Chương trình 5.4a sẽ hiển thị các thông tin như sau:

Xe thu nhat:

This is a having a speed of 0km/h and its price is $0

Xe thu hai:

This is a Mercedes having a speed of 150km/h and its price is $5000
Lí do là xe thứ nhất sử dụng hàm khởi tạo không có tham số nên xe không có tên, tốc độ và giá
đều là mặc định (0). Trong khi đó, xe thứ hai được khởi tạo đầy đủ cả ba tham số nên thông tin
giới thiệu xe được đầy đủ.

Tuy nhiên, khi đối tượng có nhiều thuộc tính riêng, để tránh trường hợp phải định nghĩa nhiều
hàm khởi tạo cho các trường hợp thiếu vắng một vài tham số khác nhau. Ta có thể sử dụng hàm
khởi tạo với các giá trị khởi đầu ngầm định. Chương trình 5.4b cho kết quả hoàn toàn giống
chương trình 5.4a, nhưng đơn giản hơn vì chỉ cần định nghĩa một hàm khởi tạo với các tham số có
giá trị ngầm định.

Chương trình 5.4b

#include<stdio.h>

#include<conio.h>

#include<string.h>

/* Định nghĩa lớp */

class Car{

private:

int speed; // Tốc độ

char mark[20]; // Nhãn hiệu

float price; // Giá xe

public:

// Khởi tạo với các giá trị ngầm điịnh cho các tham số

Car(int speedIn=0, char markIn[ ]=””, float priceIn=0);

void show(); // Giới thiệu xe

};

/* Khai báo phương thức bên ngoài lớp */

Car::Car(int speedIn, char markIn[], float priceIn){

speed = speedIn;

strcpy(mark, markIn);

price = priceIn;

}

void Car::show(){ // Phương thức giới thiệu xe

cout << “This is a ” << mark << “ having a speed of ”

<< speed << “km/h and its price is $” << price << endl;

return;

}

// Hàm main, chương trình chính

void main(){

clrscr();

Car myCar1; // Các tham số nhận giá trị mặc định

Car myCar2(150, “Mercedes”, 5000);// Dùng hàm khởi tạo đủ tham số

// Giới thiệu xe thứ nhất

cout << “Xe thu nhat: ” << endl;

myCar1.show();

// Giới thiệu xe thứ hai

cout << “Xe thu hai: ” << endl;

myCar2.show();

return;

}

5.4.2 Hàm hủy bỏ

Hàm hủy bỏđược tựđộng gọi đến khi mà đối tượng được giải phóng khỏi bộ nhớ. Nhiệm vụ của
hàm hủy bỏ là dọn dẹp bộ nhớ trước khi đối tượng bị giải phóng. Cú pháp khai báo hàm hủy bỏ
như sau:

class <Tên lớp>{

public:

~<Tên lớp>([<Các tham số>]); // Khai báo hàm khởi tạo

};

Ví dụ:

class Car{

int speed;

char *mark;

float price;

public:

~Car(){

delete [ ] mark;

};

};

là khai báo một hàm hủy bỏ của lớp Car với thuộc tính mark có kiểu con trỏ. Hàm này sẽ giải
phóng vùng nhớđã cấp phát cho con trỏ kiểu char của thuộc tính nhãn hiệu xe.

Lưu ý:

• Hàm hủy bỏ phải có tên bắt đầu bằng dấu “~”, theo sau là tên của lớp tương ứng.

• Hàm hủy bỏ không có giá trị trả về.

• Hàm hủy bỏ phải có tính chất public

• Mỗi lớp chỉ có nhiều nhất một hàm hủy bỏ. Trong trường hợp không khai báo tường minh
hàm hủy bỏ, C++ sẽ sử dụng hàm hủy bỏ ngầm định.

• Nói chung, khi có ít nhất một trong các thuộc tính của lớp là con trỏ, thì nên dùng hàm
hủy bỏ tường minh để giải phóng triệt để các vùng nhớ của các thuộc tính, trước khi đối
tượng bị giải phóng khỏi bộ nhớ.

Chương trình 5.5 minh họa việc định nghĩa lớp Car với một hàm khởi tạo có các tham số với giá
trị mặc định và một hàm hủy bỏ tường minh.

Chương trình 5.5

#include<stdio.h>

#include<conio.h>

#include<string.h>

/* Định nghĩa lớp */

class Car{

private:

int speed; // Tốc độ

char *mark; // Nhãn hiệu

float price; // Giá xe

public:

// Khởi tạo với các giá trị ngầm điịnh cho các tham số

Car(int speedIn=0, char *markIn=NULL, float priceIn=0);

void show(); // Giới thiệu xe

~Car(); // Hàm hủy bỏ tường minh

};

/* Khai báo phương thức bên ngoài lớp */

Car::Car(int speedIn, char *markIn, float priceIn){

speed = speedIn;

mark = markIn;

price = priceIn;

}

void Car::show(){ // Phương thức giới thiệu xe

cout << “This is a ” << *mark << “ having a speed of ”

<< speed << “km/h and its price is $” << price << endl;

return;

}

Car::~Car(){ // Hàm hủy bỏ tường minh

delete [ ] mark;

cout << “The object has been destroyed!” << endl;

}
// Hàm main, chương trình chính

void main(){

clrscr();

Car myCar(150, “Mercedes”, 5000);// Dùng hàm khởi tạo đủ tham số

// Giới thiệu xe

cout << “Gioi thieu xe: ” << endl;

myCar.show();

return;

}

Chương trình 5.5 sẽ in ra thông báo như sau:

Gioi thieu xe:

This is a Mercedes having a speed of 150km/h and its price is $5000

The object has been destroyed!

Dòng cuối cùng là của hàm hủy bỏ, mặc dù ta không gọi hàm hủy bỏ trực tiếp, nhưng khi thoát
khỏi hàm main() của chương trình chính, đối tượng myCar bị giải phóng khỏi bộ nhớ và khi đó,
C++ tựđộng gọi đến hàm hủy bỏ mà ta đã định nghĩa tường minh. Do vậy, mà có dòng thông báo
cuối cùng này.

5.5 CON TRỎĐỐI TƯỢNG VÀ MẢNG ĐỐI TƯỢNG

5.5.1 Con trỏđối tượng

Con trỏđối tượng là con trỏ trỏđến địa chỉ của một đối tượng có kiểu lớp. Các thao tác liên quan
đến con trỏđối tượng bao gồm:

• Khai báo con trỏđối tượng

• Cấp phát bộ nhớ cho con trỏđối tượng

• Sử dụng con trỏđối tượng

• Giải phóng bộ nhớ cho con trỏđối tượng

Khai báo con trỏđối tượng

Con trỏđối tượng được khai báo tương tự như khai báo các con trỏ có kiểu thông thường:

<Tên lớp> *<Tên con trỏ đối tượng>;

Ví dụ, muốn khai báo một con trỏđối tượng có kiểu của lớp Car, ta khai báo như sau:

Car *myCar;

Khi đó, myCar là một con trỏđối tượng có kiểu lớp Car.

Cấp phát b ộ nhớ cho con trỏđối tượng

Con trỏđối tượng cũng cần phải cấp phát bộ nhớ hoặc trỏ vào một địa chỉ của một đối tượng lớp
xác định trước khi được sử dụng. Cấp phát bộ nhớ cho con trỏđối tượng cũng bằng thao tác new:

<Tên con trỏ đối tượng> = new <Tên lớp>([<Các đối số>]);
Ví dụ, nếu lớp Car có hai hàm khởi tạo như sau:

class Car{

public:

Car();

Car(int, char[ ], float);

};

thì ta có thể cấp phát bộ nhớ theo hai cách, tương ứng với hai hàm khởi tạo của lớp:

myCar = new Car(); // Khởi tạo không tham số

myCar = new Car(100, “Ford”, 3000); // Khởi tạo đủ tham số

Lưu ý:

• Các đối số truyền phải tương ứng với ít nhất một trong các hàm khởi tạo của lớp.

• Khi sử dụng hàm khởi tạo không có tham số, ta vẫn phải sử dụng cặp ngoặc đơn “()” trong
thao tác new.

• Khi lớp không có một hàm khởi tạo tường minh nào, sẽ dùng hàm khởi tạo ngầm định của
C++ và cú pháp tương tự như sử dụng hàm khởi tạo tường minh không có tham số.

• Có thể vừa khai báo, vừa cấp phát bộ nhớ cho con trỏđối tượng.

Ví dụ:

Car myCar = new Car(); // Khởi tạo không tham số

Sử dụng con trỏđối tượng

Con trỏđối tượng được sử dụng qua các thao tác:

• Trỏđến địa chỉ của một đối tượng cùng lớp

• Truy nhập đến các phương thức của lớp

Con trỏđối tượng có thể trỏđến địa chỉ của một đối tượng có sẵn, cùng lớp theo cú pháp sau:

<Tên con trỏ đối tượng> = &<Tên đối tượng có sẵn>;

Ví dụ, ta có một con trỏ và một đối tượng của lớp Car:

Car *ptrCar, myCar(100, “Ford”,3000);

Khi đó, có thể cho con trỏ ptrCar trỏ vào địa chỉ của đối tượng myCar như sau:

ptrCar = &myCar;

Khi muốn truy nhập đến các thành phần của con trỏđối tượng, ta dùng cú pháp sau:

<Tên con trỏ đối tượng> -> <Tên thành phần lớp>([<Các đối số>]);

Ví dụ, đoạn chương trình sau sẽ thực hiện phương thức giới thiệu xe của lớp Car thông qua con
trỏ ptrCar:

Car *ptrCar = new Car(100, “Ford”,3000);

ptrCar->show();

Lưu ý:

• Danh sách các đối số phải tương thích với tên phương thức tương ứng.

• Các quy tắc phạm vi truy nhập vẫn áp dụng trong truy nhập các thành phần lớp thông qua
con trỏ.
Giải phóng bộ nhớ cho con trỏđối tượng

Con trỏđối tượng cũng được giải phóng thông qua thao tác delete:

delete <Tên con trỏ đối tượng>;

Ví dụ:

Car *ptrCar = new Car();// Khai báo và cấp phát bộ nhớ

… // Sử dụng con trỏ ptrCar

delete ptrCar; // Giải phóng bộ nhớ.

Lưu ý:

• Thao tác delete chỉđược dùng khi trước đó, con trỏđược cấp phát bộ nhớ qua thao tác
new:

Car *ptrCar = new Car();

delete ptrCar; // Đúng.

Nhưng không được dùng delete khi trước đó, con trỏ chỉ trỏ vào một địa chỉ của đối tượng
có sẵn (tĩnh):

Car *ptrCar, myCar(100, “Ford”, 3000);

ptrCar = &myCar;

delete ptrCar; // Không được

Chương trình 5.6 minh họa việc dùng con trỏđối tượng có kiểu lớp là Car.

Chương trình 5.6

#include<stdio.h>

#include<conio.h>

#include<string.h>

/* Định nghĩa lớp */

class Car{

private:

int speed; // Tốc độ

char mark[20]; // Nhãn hiệu

float price; // Giá xe

public:

// Khởi tạo với các giá trị ngầm điịnh cho các tham số

Car(int speedIn=0, char markIn[ ]=””, float priceIn=0);

void show(); // Giới thiệu xe

};

/* Khai báo phương thức bên ngoài lớp */

Car::Car(int speedIn, char markIn[ ], float priceIn){

speed = speedIn;

strcpy(mark, markIn);

price = priceIn;
}

void Car::show(){ // Phương thức giới thiệu xe

cout << “This is a ” << mark << “ having a speed of ”

<< speed << “km/h and its price is $” << price << endl;

return;

}

// Hàm main, chương trình chính

void main(){

clrscr();

// Khai báo con trỏ, cấp phát bộ nhớ dùng hàm khởi tạo đủ tham số

Car *myCar = new Car(150, “Mercedes”, 5000);

// Giới thiệu xe

cout << “Gioi thieu xe: ” << endl;

myCar->show();

// Giải phóng con trỏ

delete myCar;

return;

}

Chương trình 5.6 hiển thị ra thông báo là một lời giới thiệu xe;

Gioi thieu xe:

This is a Mercedes having a speed of 150km/h and its price is $5000

5.5.2 Mảng các đối tượng

Mảng các đối tượng cũng có thểđược khai báo và sử dụng như mảng của các biến có kiểu thông
thường.

Khai báo mảng tĩnh các đối tượng

Mảng các đối tượng được khai báo theo cú pháp:

<Tên lớp> <Tên biến mảng>[<Số lượng đối tượng>];

Ví dụ:

Car cars[10];

Là khai báo một mảng có 10 đối tượng có cùng kiểu lớp Car.

Lưu ý:

• Có thể khai báo mảng tĩnh các đối tượng mà chưa cần khai báo độ dài mảng, cách này
thường dùng khi chưa biết chính xác độ dài mảng:

Car cars[ ];

• Muốn khai báo được mảng tĩnh các đối tượng, lớp tương ứng phải có hàm khởi tạo không
có tham số. Vì khi khai báo mảng, tương đương với khai báo một dãy các đối tượng với
hàm khởi tạo không có tham số.

Khai báo mảng động với con trỏ

Một mảng các đối tượng cũng có thểđược khai báo và cấp phát động thông qua con trỏđối tượng
như sau:

<Tên lớp> *<Tên biến mảng động> = new <Tên lớp>[<Độ dài mảng>];

Ví dụ:

Car *cars = new Car[10];

Sau khi được sử dụng, mảng động các đối tượng cũng cần phải giải phóng bộ nhớ:

delete [] <Tên biến mảng động>;

Ví dụ:

Car *cars = new Car[10];// Khai báo và cấp phát động

… // Sử dụng biến mảng động

delete [] cars; // Giải phóng bộ nhớ của mảng động

Sử dụng mảng đối tượng

Khi truy nhập vào các thành phần của một đối tượng có chỉ số xác định trong mảng đã khai báo,
ta có thể sử dụng cú pháp:

<Tên biến mảng>[<Chỉ số đối tượng>].<Tên thành phần>([<Các đối số>]);

Ví dụ:

Car cars[10];

cars[5].show();

sẽ thực hiện phương thức show() của đối tượng có chỉ số thứ 5 (tính từ chỉ số 0) trong mảng cars.

Chương trình 5.7 sẽ cài đặt một chương trình, trong đó nhập vào độ dài mảng, sau đó yêu cầu
người dùng nhập thông tin về mảng các xe. Cuối cùng, chương trình sẽ tìm kiếm và hiển thị thông
tin về chiếc xe có giá đắt nhất trong mảng.

Chương trình 5.7

#include<stdio.h>

#include<conio.h>

#include<string.h>

/* Định nghĩa lớp Car */

class Car{

private:

int speed; // Tốc độ

char mark[20]; // Nhãn hiệu

float price; // Giá xe

public:

void setSpeed(int); // Gán tốc độ cho xe

int getSpeed(); // Đọc tốc độ xe

void setMark(char); // Gán nhãn cho xe

char[] getMark(); // Đọc nhãn xe

void setPrice(float); // Gán giá cho xe

float getPrice(); // Đọc giá xe

// Khởi tạo thông tin về xe

Car(int speedIn=0, char markIn[]=””, float priceIn=0);

void show(); // Giới thiệu xe

};

/* Khai báo phương thức bên ngoài lớp */

Car::Car(int speedIn, char markIn[], float priceIn){

speed = speedIn;

strcpy(mark, markIn);

price = priceIn;

}

void Car::setSpeed(int speedIn){ // Gán tốc độ cho xe

speed = speedIn;

}

int Car::getSpeed(){ // Đọc tốc độ xe

return speed;

}

void Car::setMark(char markIn){ // Gán nhãn cho xe

strcpy(mark, markIn);

}

char[] Car::getMark(){ // Đọc nhãn xe

return mark;

}

void Car::setPrice(float priceIn){ // Gán giá cho xe

price = priceIn;

}

float Car::getPrice(){ // Đọc giá xe

return price;

}

void Car::show(){ // Phương thức giới thiệu xe

cout << “This is a ” << mark << “ having a speed of ”

<< speed << “km/h and its price is $” << price << endl;

return;

}

// Hàm main, chương trình chính

void main(){

clrscr();

int length; // Chiều dài mảng

float maxPrice = 0; // Giá đắt nhất

int index = 0; // Chỉ số của xe đắt nhất

Car *cars; // Khai báo mảng đối tượng

// Nhập số lượng xe, tức là chiều dài mảng

cout << “So luong xe: ”;

cin >> length;

// Cấp phát bộ nhớ động cho mảng

cars = new Car[length];

// Khởi tạo các đối tượng trong mảng

for(int i=0;i<length; i++){

int speed; // (Biến tạm) tốc độ

char mark[20]; // (Biến tạm) nhãn hiệu

float price; // (Biến tạm) giá xe

cout << “Xe thu ” << i << “: ” <<endl;

cout << “Toc do (km/h): ”;

cin >> speed; cars[i].setSpeed(speed); // Nhập tốc độ

cout << “Nhan hieu : ”;

cin >> mark; cars[i].setMark(mark); // Nhập nhãn xe

cout << “Gia ($): ”;

cin >> price; cars[i].setPrice(price); // Nhập giá xe

if(maxPrice < price){

maxPrice = price;

index = i;

}

}

// Tìm xe đắt nhất

for(int i=0; i<length; i++)

if(i == index){

cars[i].show(); // Giới thiệu xe đắt nhất

break;

}

// Giải phóng bộ nhớ của mảng

delete [ ] cars;

return;
}

TỔNG KẾT CHƯƠNG 5

Nội dung chương 5 đã tập trung trình bày các vấn đề cơ bản về lớp đối tượng trong ngôn ngữ
C++:

• Khai báo, định nghĩa lớp bằng từ khóa class

• Sử dụng biến lớp như những đối tượng cụ thể

• Khai báo, định nghĩa các thuộc tính và các phương thức của lớp: định nghĩa các phương
thức trong hoặc ngoài phạm vi khai báo lớp

• Khai báo phạm vi truy nhập lớp bằng các từ khóa chỉ phạm vi: private, protected và
public. Giới thiệu các kiểu hàm có thể truy nhập phạm vi bất quy tắc: hàm bạn và lớp bạn
với từ khóa friend.

• Khai báo, định nghĩa tường minh hàm khởi tạo của lớp và sử dụng khi khai báo biến lớp

• Khai báo, định nghĩa tường minh hàm hủy bỏ của lớp, nhằm dọn dẹp, giải phóng bộ nhớ
trước khi đối tượng bị giải phóng khỏi bộ nhớ.

• Khai báo, cấp phát bộ nhớ, sử dụng và giải phóng bộ nhớ cho con trỏđối tượng

• Khai báo, cấp phát bộ nhớđộng, sử dụng và giải phóng vùng nhớ của mảng các đối tượng.

CÂU HỎI VÀ BÀI TẬP CHƯƠNG 5

1. Trong các khai báo lớp sau, những khai báo nào là đúng:

a. class MyClass;

b. Class MyClass;

c. class MyClass{…};

d. Class MyClass{…};

2. Giả sử ta đã định nghĩa lớp MyClass, bây giờ ta khai báo một đối tượng thuộc kiểu lớp
này. Khai báo nào là đúng:

a. class MyClass me;

b. MyClass me;

c. MyClass me();

d. MyClass me{};

3. Trong các khai báo thuộc tính ngay trong phạm vi của khai báo lớp như sau, những khai
báo nào là đúng:

a. int myAge;

b. private int myAge;

c. public int myAge;

d. private: int myAge;

4. Trong các khai báo phương thức ngay trong phạm vi của khai báo lớp MyClass như sau,
những khai báo nào là đúng:

a. public: void show();

b. void show();

c. void show(){cout << “hello!”;};

d. void MyClass::show(){cout << “hello!”;}

5. Xét đoạn chương trình sau:

class MyClass{

int age;

public:

int getAge();

};

MyClass me;

Khi đó, trong các lệnh sau, lệnh nào có thể thêm vào cuối đoạn chương trình trên:

a. cout << MyClass::age;

b. cout << me.age;

c. cout << me.getAge();

d. cin >> me.age;

6. Trong các khai báo hàm khởi tạo cho lớp MyClass như sau, những khai báo nào là đúng:

a. myClass();

b. MyClass();

c. MyClass(MyClass);

d. void MyClas();

e. MyClass MyClass();

7. Trong các khai báo hàm hủy bỏ cho lớp MyClass như sau, những khai báo nào là đúng:

a. ~myClass();

b. ~MyClass();

c. ~MyClass(MyClass);

d. void ~MyClas();

e. MyClass ~MyClass();

8. Giả sử ta khai báo lớp MyClass có một thuộc tính age và một hàm khởi tạo:

class MyClass{

int age;

public:

MyClass(MyClass me){



};

int getAge(){return age};

};


Trong các dòng lệnh sau, những dòng nào có thể xuất hiện trong hàm khởi tạo trên:

a. age = MyClass.age;

b. age = me.age;

c. age = MyClass.getAge();

d. age = me.getAge();

e. age = 10;

9. Xét khai báo lớp như sau:

class MyClass{

public:

MyClass(MyClass);

MyClass(int);

};

Khi đó, trong số các khai báo đối tượng sau, những khai báo nào là đúng:

a. MyClass me;

b. MyClass me();

c. MyClass me(10);

d. MyClass me1(10), me2(me1);

10. Xét khai báo lớp như sau:

class MyClass{

public:

MyClas
luongbv93
luongbv93
Admin

Tổng số bài gửi : 117
Points : 354
Reputation : 0
Join date : 18/11/2011
Age : 30
Đến từ : Hà Nội

https://diendanteenviet.forumvi.com

Về Đầu Trang Go down

Về Đầu Trang

- Similar topics

 
Permissions in this forum:
Bạn không có quyền trả lời bài viết