Khai báo lớp: thuộc tính 1/5 Là dữ liệu khai báo trong lớp Cú pháp giống như khai báo biến Có thể là một đối tượng nhưng phải khác đối tượng của lớp đang định nghĩa con trỏ hay tham chiế
Trang 2Nội dung
1 Khái niệm lớp và đối tượng
2 Toán tử gán
3 Phương thức thiết lập (constructor)
4 Phương thức huỷ (destructor)
5 Con trỏ this
6 Lớp template
Trang 5Với member_list là đặc tả các thành viên
Theo quy ước, tên lớp bắt đầu bởi ký tự C
Trang 6Khai báo lớp (2/2)
Thành viên của lớp gồm
Thành viên dữ liệu (data member) thuộc tính
Hàm thành viên (member function) phương
Trang 7Khai báo lớp: thuộc tính (1/5)
Là dữ liệu khai báo trong lớp
Cú pháp giống như khai báo biến
Có thể là một đối tượng nhưng phải khác đối tượng của lớp đang định nghĩa (con trỏ hay tham chiếu: OK)
Không thể vừa khai báo, vừa khởi tạo
Trang 8Khai báo lớp: thuộc tính (2/5)
class CTime //Lớp thời gian{
private:
int hour = 1; // Error
int minute, second;
public:
void SetTime(int h, int m, int s);void Print();
};
Trang 9Khai báo lớp: phương thức (3/5)
Hàm khai báo trong lớp (còn gọi là giao diện)
Có thể truy cập các thành viên dữ liệu và hàm thành viên khác
Cài đặt trong lớp hàm inline
Trang 11Khai báo lớp: cài đặt phương thức (5/5)
class CMyTime {
Trang 12Thuộc tính truy xuất thành viên (1/3)
(member access specifier)
Xác định phạm vi của các thành viên của lớp có thể được sử dụng trực tiếp từ bên ngoài phạm vi lớp hay không
Các thuộc tính: private, protected, public
Trang 13public (mặc định đối với thành viên của struct)
Có thể được truy xuất từ bên ngoài lớp
Trang 14cout << x << "," << y << endl;
} };
void f() {
CMyClass m;
cout<<m.x; // Error
cout<<m.y; //OK m.Print(); //OK }
Trang 15Sử dụng lớp đối tượng (1/4)
Tạo đối tượng
Sử dụng lớp giống như dùng struct, khai báo một biến lớp (tạo đối tượng) như khai báo biến struct
Khai báo con trỏ, tham chiếu tới lớp
Có thể khai báo con trỏ/ tham chiếu đến một đối tượng thuộc cùng lớp (truy cập gián tiếp)
Con trỏ/ tham chiếu không là instance của lớp
Trang 16t3->SetTime(1, 5, 7); t3->Print();
Trang 17Sử dụng lớp đối tượng (3/4)
Mỗi đối tượng sẽ có một tập các dữ liệu riêng
(thuộc tính) được định nghĩa trong lớp
Tuy nhiên, tập các đối tượng thuộc cùng một lớp chỉ có chung duy nhất các định nghĩa hàm (phương thức)
Trang 18Sử dụng đối tượng (4/4)
SetTime() Print()
hour=12 minute=5 second=5
hour=11 minute=15 second=15
Trang 20Toán tử gán (2/2)
Mỗi thành viên của một đối tượng này được sao chép riêng rẽ đến cùng một thành viên tương ứng của đối tượng khác
Chú ý đối với các thành viên dữ liệu chứa vùng nhớ cấp phát động hoặc con trỏ
Trang 21Phương thức thiết lập (Constructor) (1/9)
Khởi tạo các thành viên dữ liệu khi đối tượng được tạo ra
Constructor được gọi tự động mỗi khi một instance của lớp được tạo
Constructor thường được dùng để khởi tạo giá trị ban đầu hoặc cấp phát động cho các thành viên dữ liệu
Trang 22Phải có thuộc tính truy xuất là public
Constructor có thể có tham số (kể cả tham số mặc định) và đa năng hóa
Trang 23} void main() {
CMyTime t1; //gọi constructor (1) t1.Print();
CMyTime t2(5,15,30);//gọi constructor (2)
t2.Print();
}
Trang 25Mỗi lớp có duy nhất một constructor mặc định
Nếu không định nghĩa thì TBD sẽ tự tạo một constructor mặc định và constructor này rỗng (không làm gì) Thành viên dữ liệu sẽ có giá trị
“rác”
Trang 26Phương thức thiết lập mặc định (6/9)
class CMyTime {
Trang 27Phương thức thiết lập sao chép (7/9)
(Copy Constructor)
Tạo ra 01 đối tượng mới giống với 01 đối tượng đã có
Có 01 tham số là một tham chiếu đến 01 đối tượng của cùng lớp
C++ cung cấp sẵn constructor sao chép: sao chép từng thành viên dữ liệu từ đối tượng cũ sang đối tượng mớiNếu cần thực hiện các công việc khởi tạo khác
Định nghĩa lại constructor sao chép
Trang 28CMyTime(CMyTime & t); //Copy constructor
… };
Trang 29Phương thức thiết lập sao chép (9/9)
Toán tử gán vs Constructor sao chép
Toán tử gán không tạo ra đối tượng mới: chỉ thực hiện phép gán giữa 2 đối tượng đã tồn tại
Constructor sao chép được dùng để tạo một đối tượng mới và gán nội dung của một đối tượng đã tồn tại cho đối tượng mới vừa tạo
Trang 30Phương thức huỷ (Destructor) (1/4)
Tự động gọi khi đối tượng bị hủy bỏ (đối tượng rời khỏi phạm vi của nó)
Đặc điểm
Tên trùng với tên lớp & theo sau bởi ký tự “~”
Không có tham số & không có trả về giá trị
Phải có thuộc tính truy xuất là public
Trang 31Phương thức huỷ (2/4)
Đặc điểm
Chỉ có duy nhất một destructor trong lớp
Nếu một lớp không có định nghĩa destructor thì TBD sẽ tạo ra một destructor mặc định rỗng
Destructor thường được dùng để thực hiện việc giải phòng vùng nhớ đã được cấp phát trước khi một đối tượng bị huỷ bỏ
Trang 34Đối tượng hằng & thành viên hằng (1/7)
Dùng từ khóa const đối với đối tượng của một lớp để báo cho biết đối tượng đó không thể thay đổi
const CMyTime t(1,20,30);
t.SetTime(2,20,30); // Error
t.Print(); // Error???
Trang 35Đối tượng hằng & thành viên hằng (2/7)
Khi một đối tượng là hằng, một số TBD cấm hoàn toàn gọi bất kỳ hàm thành viên nào của đối tượng
đó, một số TBD thì đưa cảnh báo (warning)
Để khắc phục, có thể khai báo các hàm thành viên
là hằng Để đảm bảo nó không sửa đổi đối tượng
Trang 36Đối tượng hằng & thành viên hằng (3/7)
class CMyTime {
//Thiet lap hour
void SetMinute(int m); //Thiet lap minute
void SetSecond(int s);
//Thiet lap second
//Cac ham get int GetHour() const; //Tra ve hour int GetMinute() const; //Tra ve minute int GetSecond() const; //Tra ve second void Print() const;
};
Trang 37Đối tượng hằng & thành viên hằng (4/7)
CMyTime::CMyTime(int h, int m, int s)
return minute;
} int CMyTime::GetSecond() const {
return second;
} void CMyTime::Print() const {
cout<<hour<<":"<<minute<<":"; cout<<second<<endl;
}
Trang 39Thành viên dữ liệu hằng
Phải cung cấp một bộ khởi tạo thành viên (member initializer) cho constructor để khởi tạo giá trị ban đầu cho thành viên dữ liệu đó
Nếu có nhiều thành viên dữ liệu hằng thì phải cung cấp nhiều bộ khởi tạo thành viên cách nhau bởi dấu phẩy
Đối tượng hằng & thành viên hằng (6/7)
Trang 40CMyClass::CMyClass(int c, int a) : x(a), y(a)
{
count = c;
}
Trang 41Thành viên là đối tượng của lớp khác (1/5)
Khi một đối tượng đi vào phạm vi, constructor của
nó được gọi một cách tự động Cần phải mô tả các tham số được truyền tới các constructor của đối tượng thành viên
Các đối tượng thành viên được xây dựng theo thứ
tự mà chúng được khai báo và trước đối tượng của lớp chứa chúng
Trang 42Thành viên là đối tượng của lớp khác (2/5)
class CDate
{
int day, month, year;
int TestDay (int d);
year=y;
day=TestDay (d);
}
Trang 43Thành viên là đối tượng của lớp khác (3/5)
int CDate::TestDay (int d)
{
static int days[]={31,28,31,30,31,30,31,31,30,31,30,31};
if ((d>0) && (d<=days [ month -1]))
Trang 44Thành viên là đối tượng của lớp khác (4/5)
CPerson::CPerson (char *st,int bday,int bmonth,int byear,int wday,int wmonth,int
wyear) : birth_day (bday, bmonth, byear), work_day (wday, wmonth, wyear)
Trang 45Thành viên là đối tượng của lớp khác (5/5)
Một đối tượng thành viên cần được khởi tạo thông qua một bộ khởi tạo thành viên
Nếu một bộ khởi tạo thành viên không được cung cấp thì constructor mặc định của đối tượng thành viên sẽ được gọi một cách tự động
Trang 46Hàm friend (1/4)
Được định nghĩa bên ngoài phạm vi của lớp đó
Không phải là phương thức của lớp
Có quyền truy cập đến các thành viên private và protected
Trang 48Hàm friend: Hàm toàn cục (3/4)
class CCount {
private:
int x ; public:
CCount () {
Trang 49… };
class A {
…
friend int B::fa(A x);
};
Trang 50Lớp friend
Một lớp là friend của một lớp khác thì tất cả các hàm thành viên của lớp này đều là friend của lớp đó
Cú pháp:
friend class_name;
class B;
class A {
…
friend class B;
… };
Trang 51Con trỏ this (1/6)
Xác định chính xác đối tượng nào đang gọi để nó truy cập đến đúng dữ liệu của đối tượng tương ứngMỗi đối tượng có một con trỏ this lưu địa chỉ của đối tượng (trỏ đến chính nó) để khi mỗi lần gọi một hàm this được truyền cho hàm đó để hàm biết chính xác đối tượng nào đang gọi
Trang 52Con trỏ this (2/6)
Khi nào sử dụng con trỏ this?
Khi trong phương thức muốn trả về đối tượng đang gọi hàm
Phương thức cần lưu lại đối tượng cũ trước khi thay đổi dữ liệu
Để phân biệt thành viên dữ liệu trong đối tượng với biến của riêng hàm khi trùng tên
Trang 53int x; public:
A(int x);
… };
A::A(int x) {
this -> x = x;
}
Trùng tên (? phân biệt)
Trang 54CMyTime & SetTime(int h, int m, int s);
CMyTime & SetHour(int h); //Thiet lap hour
CMyTime & SetMinute(int m); //Thiet lap minute
CMyTime & SetSecond(int s); //Thiet lap second
//Cac ham get int GetHour() const; //Tra ve hour int GetMinute() const; //Tra ve minute int GetSecond() const; //Tra ve second void Print() const;
Trang 55Con trỏ this (5/6)
CMyTime::CMyTime(CMyTime & t) {
hour=t.hour;
minute=t.minute;
second=t.second;
} CMyTime & CMyTime::SetTime(int h, int m, int s) {
hour=(h>=0 && h<24)?h:0;
return *this;
} CMyTime & CMyTime::SetMinute(int m) {
minute=(m>=0 && m<60)?m:0;
return *this;
}
Trang 57Thành viên tĩnh (static) (1/5)
Mỗi đối tượng của một lớp có bản sao chép của chính nó cho tất cả các thành viên dữ liệu của lớpMuốn có duy nhất một bản sao thành viên dữ liệu dùng chung cho tất cả các đối tượng của lớp
toàn cục nhưng nằm trong một lớp nào đó (độc lập với các đối tượng)
Trang 58Thành viên tĩnh (2/5)
Hàm thành viên muốn truy cập đến thành viên dữ liệu tĩnh thì hàm thành viên đó phải là hàm thành viên tĩnh
Các thành viên tĩnh có thể tồn tại ngay cả khi không có đối tượng của lớp đó
Muốn thành viên của lớp là thành viên tĩnh, thêm
từ khóa static phía trước
Trang 59Thành viên tĩnh (3/5)
Thành viên dữ liệu tĩnh phải được khởi tạo trước khi
sử dụng Được khởi tạo bên ngoài lớp theo cú pháp:
type class_name :: static_data_member_name = value;
Để truy cập thành viên tĩnh không thông qua đối tượng, thêm vào đầu tên lớp và toán tử định phạm vi
class_name :: static_data_member_name
class_name :: method_name (parameters)
Trang 60Hàm thành viên tĩnh không được là hàm thành viên hằng
Trang 61CChicken t;
t.CounterDisplay();
}
Trang 62t2[1].Print();
Trang 63Cấp phát động cho đối tượng (1/2)
Các đối tượng có thể cấp phát động giống như các
dữ liệu khác thông qua các toán tử new và delete
Toán tử new tự động gọi hàm constructor và toán
tử delete tự động gọi destructor
Trang 65Lấy địa chỉ của một thành viên
& class_name :: member_name
->* Truy cập tới thành viên khi đối tượng của lớp &
thành viên của đối tượng đều xác định bởi con trỏ
.*
Được sử dụng khi đối tượng được chỉ ra trực tiếp còn các thành viên của nó thì được xác định nhờ con trỏ
Trang 66cout<<endl;
} };
Trang 67 template < class identifier > class_declaration
template < typename identifier > class_declaration
Trang 70void Fun();
};
template <class T, int n>
void CTable <T, n> ::Fun() {
… }
CTable <int, 10> x;
Trang 72Lớp template (6/9)
template <class T, int n>
class CTable {
private:
T a[n]
… public:
void Fun();
};
template <class T, int n>
void CTable <T, n> ::Fun() {
… }
CTable <int, 10> x;
CTable <int, 10> t1; CTable <float, 10> t2;
t2 = t1; //Error
CTable <int, 10> t3; CTable <int, 12> t4;
t4 = t3; //Error
CTable <int, 10> t5; CTable <int, 10> t6; t6 = t5; //OK
Trang 73friend class A;
friend int Fun(int);
… };
Trang 74… } ; template <class T>
int F(T a) {
… }
template <class T>
class CMyClass {
…
friend class CMyPoint<int>; friend int F(float);
… };
Trang 75template <class T>
int F(T a)
{
… }
template <class T>
class CMyClass
{
…
template <class U>friend class CMyPoint<U>;
template <class U>friend int F(U);
… };
Hàm template và lớp template là friend
Trang 76Q&A