1. Hàm khởi tạo (constructor)
1.1. Hàm khởi tạo là gì?
Hàm khởi tạo là một hàm đặc biệt trong lớp. Hàm này được gọi tự động khi một đối tượng được tạo ra. Hàm khởi tạo sẽ khởi tạo giá trị cho các thuộc tính của đối tượng. Trong C++, một hàm khởi tạo có đặc điểm sau:
− Tên hàm khởi tạo trùng với tên của lớp.
− Hàm khởi tạo không có kiểu dữ liệu trả về (kể cả void).
− Hàm khởi tạo phải được khai báo với phạm vi truy cập là public.
− Hàm khởi tạo có thể có đối số hoặc không có đối số.
− Trong một lớp có thể có nhiều hàm khởi tạo (cùng tên nhưng khác đối số).
Ví dụ:
class Circle{
private:
float r;
public:
//Hàm khởi tạo không có tham số
Circle(){
this->r = 1.0;
}
//Hàm khởi tạo có tham số
Circle(float r){
this->r = r;
}
void setRadius(float r){
this->r = r;
}
float getRadius(){
return r;
}
float calculateArea(){
return 3.14 * r * r;
}
};
1.2. Hàm khởi tạo mặc định (default constructor)
Hàm khởi tạo mà không có đối số nào thì được gọi là hàm khởi tạo mặc định. Hàm này thường dùng gán giá trị mặc định cho các thuộc tính trong lớp.
Trong ví dụ bên dưới, hàm Circle()
là một hàm khởi tạo mặc định.
class Circle{
private:
float r;
public:
Circle(){
r = 1.0;
}
void setRadius(float r){
this->r = r;
}
float getRadius(){
return r;
}
float calculateArea(){
return 3.14 * r * r;
}
};
void main()
{
Circle c;//sử dụng hàm khởi tạo mặc định
cout<<"Area of Circle = "<<c.calculateArea();
system("pause");
}
Kết quả
Area of Circle = 3.14
Lưu ý: Nếu lớp không có hàm khởi tạo nào, trình biên dịch sẽ cung cấp một hàm khởi tạo mặc định không đối số và không code trong nó.
1.3. Khởi tạo đối tượng với hàm khởi tạo
Nếu trong lớp đã có ít nhất một hàm khởi tạo thì hàm khởi tạo mặc định do trình biên dịch cung cấp sẽ không còn nữa. Khi đó, bạn phải sử dụng các hàm khởi tạo được định nghĩa trong lớp nếu không sẽ gây ra lỗi.
class Circle{
private:
float r;
public:
//Hàm khởi tạo có tham số
Circle(float r){
this->r = r;
}
void setRadius(float r){
this->r = r;
}
float getRadius(){
return r;
}
float calculateArea(){
return 3.14 * r * r;
}
};
void main()
{
Circle c;//lỗi vì không có hàm khởi tạo mặc định
Circle c1(3.5);//ok vì có hàm khởi tạo được định nghĩa
system("pause");
}
1.4. Hàm khởi tạo sao chép (copy constructor)
Có thể khai báo và khởi tạo một đối tượng mới từ một đối tượng đã tồn tại.
Circle c1(10); //Khai báo và khởi tạo đối tượng c1
Circle c2(c1); //Khai báo đối tượng c2 dùng đối tượng c1
Trong C++, câu lệnh Circle c2 (c1);
sẽ gọi tới một hàm khởi tạo sao chép mặc định. Hàm này sẽ sao chép nội dung từng bit của c1 vào các bit tương ứng của c2.
Ta cũng có thể tự tạo một hàm khởi tạo sao chép với cú pháp như sau:
Tên_lớp (Tên_lớp &obj){
/* Các câu lệnh dùng các thuộc tính của đối tượng obj để gán cho các thuộc tính của đối tượng mới*/
}
Ví dụ:
class Circle{
private:
float r;
public:
Circle(Circle &c){
this->r = c.r;
}
//Hàm khởi tạo có tham số
Circle(float r){
this->r = r;
}
void setRadius(float r){
this->r = r;
}
float getRadius(){
return r;
}
float calculateArea(){
return 3.14 * r * r;
}
};
void main()
{
Circle c1(10);
Circle c2(c1);//sử dụng hàm khởi tạo sao chép
cout<<"Area of Circle c2 = "<<c2.calculateArea();
system("pause");
}
Kết quả
Area of Circle c2 = 314
2. Hàm hủy (destructor)
Hàm huỷ sẽ tự động được gọi trước khi giải phóng một đối tượng để giải phóng vùng nhớ trước khi đối tượng được hủy bỏ. Hàm hủy có các đặc điểm sau:
− Mỗi lớp chỉ có một hàm hủy.
− Hàm hủy không có kiểu, không có giá trị trả về và không có đối số.
− Tên hàm huỷ cùng tên với tên lớp và có một dấu ngã (~) ngay trước tên.
Ví dụ:
#include <iostream>
using namespace std;
class Circle{
private:
float r;
public:
//Hàm khởi tạo có tham số
Circle(float r){
this->r = r;
}
void setRadius(float r){
this->r = r;
}
float getRadius(){
return r;
}
float calculateArea(){
return 3.14 * r * r;
}
~Circle(){
cout<<"Radius of circle has destroyed."<<endl;
}
};
void main()
{
Circle c1(3.5);
cout<<"Area of Circle = "<<c1.calculateArea();
}
Kết quả
Area of Circle = 38.465
Radius of circle has destroyed.
Lưu ý: Nếu trong lớp không định nghĩa hàm huỷ thì hàm huỷ mặc định được sử dụng. Hàm hủy này sẽ không làm gì cả.