Các ặc điểm cơ bản của C++ như const, static, . ápdụng cho các lớp như thế nào?
hằng thành viên– const member
thành viêntĩnh– static member
hằng thành viêntĩnh– const static member
hằng hàm/phương thức– const method
hàm/phương thức tĩnh– static method
làm việcvới các ối tượng
15 trang |
Chia sẻ: haohao89 | Lượt xem: 2529 | Lượt tải: 2
Bạn đang xem nội dung tài liệu Bài giảng Các đặc điểm C++ áp dụng cho class, để tải tài liệu về máy bạn click vào nút DOWNLOAD ở trên
Các đặc điểm C++
áp dụng cho class
Lập trình hướng đối tượng
@ 2004 Trần Minh Châu. FOTECH. VNU 2
Tài liệu đọc
n Eckel, Bruce. Thinking in C++, 2nd Ed. Vol 1.
¨ Chapter 8: Constants
n Start at p. 352 (Classes)
¨ Chapter 10: Name Control
n p. 423 (Static Members in C++) to p. 442 (Alternate Linkage
Specifications)
n Dietel. C++ How to Program, 4th Ed.
¨ Chapter 7: Class II
n 7.2, 7.3, 7.6, 7.7, 7.8
@ 2004 Trần Minh Châu. FOTECH. VNU 3
Tổng quan
n Các đặc điểm cơ bản của C++ như const, static, ... áp
dụng cho các lớp như thế nào?
¨ hằng thành viên – const member
¨ thành viên tĩnh – static member
¨ hằng thành viên tĩnh – const static member
¨ hằng hàm/phương thức – const method
¨ hàm/phương thức tĩnh – static method
¨ làm việc với các đối tượng
@ 2004 Trần Minh Châu. FOTECH. VNU 4
Hằng thành viên – const member
n Ta đã biết về từ khoá const dùng với các biến thông thường
const int x = 50;
n Từ khoá const đối với các thành viên dữ liệu như thế nào?
n Khi một thành viên dữ liệu được khai báo là const, thành viên đó
sẽ giữ nguyên giá trị trong suốt thời gian sống của đối tượng chủ.
class MyClass {
public:
MyClass(int x = 5); // Constructor w/default argument
private:
const int foo; // Declares foo a constant member
};
@ 2004 Trần Minh Châu. FOTECH. VNU 5
Hằng thành viên – const member
khởi tạo hằng thành viên khi nào?
n Bên trong khai báo class? Quá sớm, ta chưa có đối
tượng nào, không có chỗ để lưu giá trị
n Gán trị trong thân hàm constructor? Quá muộn, không
đảm bảo hằng không được truy nhập trước khi nó được
gán.
n Giải pháp: danh sách khởi tạo tại constructor – member
initialization list
@ 2004 Trần Minh Châu. FOTECH. VNU 6
Hằng thành viên – const member
n danh sách khởi tạo của constructor nằm tại định nghĩa của
constructor, chứa một tập các "lời gọi constructor" mà sẽ được thực
hiện trước khi thực thi phần thân của constructor đó.
¨ khi dùng cho các hằng thành viên, danh sách khởi tạo đảm bảo chúng
được khởi tạo trước khi được truy nhập
¨ chi tiết thêm tại phần thừa kế.
class MyClass {
public:
MyClass(int x = 5); // Constructor w/default argument
private:
const int foo; // Declares foo a constant member
};
...
MyClass::MyClass(int x) : foo(x)
{ // constructor body }
danh sách khởi tạo của
constructor
dấu hai chấm tách giữa
danh sách tham số và
danh sách khởi tạo
@ 2004 Trần Minh Châu. FOTECH. VNU 7
Hằng thành viên – const member
n Danh sách khởi tạo – Ví dụ
class MyClass {
public:
MyClass(int x = 5); // Constructor w/default argument
private:
const int foo; // Declares foo a constant member
const int bar;
};
...
MyClass::MyClass(int x, int y) : foo(x), bar(y)
{ // constructor body }
danh sách khởi tạo của constructor,
khởi tạo hằng foo với giá trị của x ,
khởi tạo hằng bar với giá trị của y.
dấu phảy tách giữa các
thành phần của danh sách
khởi tạo
@ 2004 Trần Minh Châu. FOTECH. VNU 8
Hằng thành viên – const member
n Điều quan trọng cần nhớ: hằng thành viên của một đối
tượng không thay đổi giá trị trong suốt thời gian sống
của đối tượng đó.
¨ Các hằng của các đối tượng khác nhau (thuộc cùng một lớp)
không có quan hệ gì với nhau
¨ Ví dụ, một đối tượng thuộc lớp MyClass có hằng foo với giá trị
5, trong khi đó, một đối tượng khác cùng thuộc lớp MyClass lại
có hằng foo có giá trị 10.
n Tiếp theo, ta sẽ tìm hiểu cách định nghĩa các thành viên
dữ liệu được dùng chung bởi tất cả các đối tượng thuộc
cùng một lớp
@ 2004 Trần Minh Châu. FOTECH. VNU 9
Thành viên tĩnh – static member
void myCounter()
{
static int count = 0; // Static variable
count++;
cout << “This function has been invoked “
<< count << “ time(s). << endl;
}
int main()
{
for (int i = 1; i <= 3; i++)
{
myCounter();
}
}
This function has been invoked 1 time(s).
This function has been invoked 2 time(s).
This function has been invoked 3 time(s).
n Đối với biến thông thường, static dùng để khai báo các biến tĩnh
tồn tại trong suốt quá trình chạy của chương trình.
@ 2004 Trần Minh Châu. FOTECH. VNU 10
Thành viên tĩnh – static member
Tương tự giữa biến tĩnh và thành viên tĩnh
n biến static x được khai báo trong hàm f(),
¨ một bản duy nhất tồn tại trong suốt quá trình chạy của chương trình.
¨ dùng chung cho tất cả các lần chạy hàm f(),
¨ bất kể hàm f() được gọi bao nhiêu lần
n Đối với class, static dùng để khai báo thành viên dữ liệu dùng
chung cho mọi thể hiện của lớp.
¨ một bản duy nhất tồn tại trong suốt quá trình chạy của chương trình,
¨ dùng chung cho tất cả các thể hiện của lớp,
¨ bất kể lớp đó có bao nhiêu thể hiện
@ 2004 Trần Minh Châu. FOTECH. VNU 11
n Đếm số đối tượng MyClass
¨ khai báo lớp MyClass
Thành viên tĩnh - Ví dụ
class MyClass {
public:
MyClass(); // Constructor
~MyClass(); // Destructor
void printCount(); // Output current value of count
private:
static int count; // static member to store
// number of instances of MyClass
};
thành viên tĩnh count
@ 2004 Trần Minh Châu. FOTECH. VNU 12
¨cài đặt các phương thức
Thành viên tĩnh - Ví dụ
int MyClass::count = 0;
MyClass::MyClass() {
this->count++; // Increment the static count
}
MyClass::~MyClass() {
this->count--; // Decrement the static count
}
void MyClass::printCount() {
cout count
<< " instance(s) of MyClass.\n";
}
Khởi tạo biến đếm bằng 0, vì
ban đầu không có đối tượng nào
@ 2004 Trần Minh Châu. FOTECH. VNU 13
Thành viên tĩnh – static member
Định nghĩa và khởi tạo
n thành viên tĩnh được lưu trữ độc lập với các thể hiện của lớp, do đó,
các thành viên tĩnh phải được định nghĩa
int MyClass::count;
n ta thường định nghĩa các thành viên tĩnh trong file chứa định nghĩa
các phương thức
n nếu muốn khởi tạo giá trị cho thành viên tĩnh ta cho giá trị khởi tạo
tại định nghĩa
int MyClass::count = 0;
@ 2004 Trần Minh Châu. FOTECH. VNU 14
Thành viên tĩnh – static member
int main()
{
MyClass* x = new MyClass;
x->PrintCount();
MyClass* y = new MyClass;
x->PrintCount();
y->PrintCount();
delete x;
y->PrintCount();
}
There are currently 1 instance(s) of MyClass.
There are currently 2 instance(s) of MyClass.
There are currently 2 instance(s) of MyClass.
There are currently 1 instance(s) of MyClass.
¨ chương trình demo sử dụng MyClass
@ 2004 Trần Minh Châu. FOTECH. VNU 15
Hằng thành viên tĩnh
n Kết hợp hai từ khoá const và static, ta có hiệu quả kết hợp
¨ một thành viên dữ liệu được định nghĩa là static const là một hằng
được chia sẻ giữa tất cả các đối tượng của một lớp.
n Không như các thành viên khác, các thành viên static const phải
được khởi tạo khi khai báo
class MyClass
{
public:
MyClass();
~MyClass();
private:
static const int thirteen = 13;
};
int main()
{
MyClass x;
MyClass y;
MyClass z;
}
x, y, z dùng chung một thành viên
thirteen có giá trị không đổi là 13
@ 2004 Trần Minh Châu. FOTECH. VNU 16
Hằng thành viên tĩnh
n Tóm lại, ta nên khai báo:
¨ static
đối với các thành viên dữ liệu ta muốn dùng chung cho mọi thể
hiện của một lớp
¨ const
đối với các thành viên dữ liệu cần giữ nguyên giá trị trong suốt
thời gian sống của một thể hiện
¨ static const
đối với các thành viên dữ liệu cần giữ nguyên cùng một giá trị tại
tất cả các đối tượng của một lớp
@ 2004 Trần Minh Châu. FOTECH. VNU 17
Hằng phương thức – const method
n Từ khoá const được dùng cho các tham số của hàm để
đảm bảo các tham số được truyền cho hàm sẽ không bị
hàm sửa đổi.
int myFunction(const int& x);
n Cú pháp này cũng được dùng cho phương thức với hiệu
quả tương tự
class MyClass {
//...
MyMethod(const int& x);
///...
};
x được truyền bằng hằng tham chiếu
x sẽ không bị hàm/phương thức sửa đổi
@ 2004 Trần Minh Châu. FOTECH. VNU 18
Hằng phương thức – const method
n Còn tham số ẩn truyền bằng con trỏ this và chính là đối
tượng chủ?
n Hằng phương thức là cú pháp cho phép ta đảm bảo với
trình biên dịch rằng phương thức sẽ không sửa đổi đối
tượng chủ
class MyClass {
...
void printCount() const;
...
};
...
void MyClass::PrintCount() const
{
// ...
}
phải có từ khóa const ở cả khai báo
và định nghĩa phương thức
@ 2004 Trần Minh Châu. FOTECH. VNU 19
Hằng phương thức – const method
n Đối với các hằng đối tượng, trình biên dịch chỉ cho phép
gọi các hằng phương thức
¨ để đảm bảo nó không sửa đổi đối tượng chủ
n Trình biên dịch sẽ báo lỗi nếu một hằng phương thức
sửa đổi giá trị của thành viên bất kỳ của đối tượng
¨ Tuy nhiên, hằng phương thức được phép sửa giá trị của các
thành viên dữ liệu tĩnh của lớp
n do các thành viên tĩnh độc lập với các đối tượng, như vậy sửa đổi
chúng không vi phạm tính bất biến của đối tượng
n Nói chung, ta nên khai báo mọi phương thức truy vấn là
hằng, vừa để báo với trình biên dịch, vừa để tự gợi nhớ.
@ 2004 Trần Minh Châu. FOTECH. VNU 20
Phương thức tĩnh – static method
n Từ khoá static còn được dùng cho các phương thức
à phương thức tĩnh
n Một phương thức tĩnh có thể được gọi một cách độc lập
với mọi thể hiện của lớp
¨ phương thức tĩnh không được truyền con trỏ this làm tham số
ẩn.
¨ không thể sửa đổi các thành viên dữ liệu từ trong phương thức
tĩnh.
¨ có thể gọi phương thức tĩnh mà không cần tạo thể hiện nào của
lớp - gọi thẳng bằng tên lớp
@ 2004 Trần Minh Châu. FOTECH. VNU 21
Phương thức tĩnh – static method
n Khai báo:
class MyClass
{
public:
MyClass(); // Constructor
~MyClass(); // Destructor
static void printCount(); // Output current value of count
private:
static int count; // count
};
n dùng tên lớp kèm theo toán tử phạm vi (::) để gọi phương thức tĩnh
MyClass::printCount();
n hoặc có thể dùng đối tượng sẵn có để gọi phương thức tĩnh
MyClass x;
x.printCount();
@ 2004 Trần Minh Châu. FOTECH. VNU 22
Phương thức tĩnh – static method
n Ví dụ int main(){
MyClass::printCount();
MyClass* x = new MyClass;
x->printCount();
MyClass* y = new MyClass;
x->printCount();
y->printCount();
delete x;
y->printCount();
}
There are currently 0 instance(s) of MyClass.
There are currently 1 instance(s) of MyClass.
There are currently 2 instance(s) of MyClass.
There are currently 2 instance(s) of MyClass.
There are currently 1 instance(s) of MyClass.
@ 2004 Trần Minh Châu. FOTECH. VNU 23
Hằng đối tượng – const object
n hằng đối tượng:
¨ trình biên dịch sẽ đảm bảo rằng không một thành viên
dữ liệu nào có thể bị sửa đổi sau khi đối tượng được
khởi tạo
n kể cả các thành viên public không phải là hằng
¨ khai báo:
const MyClass x(5); // x là hằng
n Khi làm việc với hằng đối tượng, ta chỉ có thể
gọi các hàm thành viên là hằng - const hoặc
tĩnh - static
@ 2004 Trần Minh Châu. FOTECH. VNU 24
Hằng đối tượng. Ví dụ
class MyClass
{
public:
MyClass();
~MyClass();
static void printCount();
void foo() const;
void bar();
const int x;
int y;
...
};
const MyClass x;
cout << x.x; //no change – OK
cout << x.y; //no change – OK
x.x++; //Error
x.y++; //Error
const MyClass x;
x.printCount(); // static - OK
x.foo(); // const - OK
x.bar(); // non-const - error
không thể sửa thành viên, dù là
public không phải hằng
chỉ được gọi hàm thành viên
là hằng hoặc tĩnh
@ 2004 Trần Minh Châu. FOTECH. VNU 25
Làm việc với đối tượng
n Đến đây, ta đã gặp các ví dụ về cách khai báo, khởi tạo,
và làm việc với các đối tượng
n Trước khi tiếp tục, ta nên tóm tắt lại một số cách sử
dụng đối tượng trong C++
n Kèm thêm một số lưu ý về vấn đề liên quan tới quản lý
bộ nhớ và lập trình hướng đối tượng
@ 2004 Trần Minh Châu. FOTECH. VNU 26
Làm việc với đối tượng
n Điều quan trọng cần nhớ về các đối tượng là: tại cốt lõi,
chúng chẳng qua chỉ là các kiểu dữ liệu người dùng tự
định nghĩa
n Có nghĩa là, hầu như tất cả những gì ta có thể làm đối
với các kiểu dữ liệu cài sẵn, ta cũng có thể thực hiện đối
với các lớp
@ 2004 Trần Minh Châu. FOTECH. VNU 27
Làm việc với đối tượng
MyClass foo;
MyClass foo2(5,6);n Khai báo các đối tượng
MyClass* foo;
foo = new MyClass();
MyClass* foo2;
foo2 = new MyClass(5, 6);
...
delete foo;
delete foo2;
n Khai báo con trỏ tới đối
tượng, và dùng con trỏ để
cấp phát bộ nhớ động
...rồi thu hồi chúng
MyClass foo;
MyClass& r_foo = foo;
MyClass foo2;
MyClass& r_foo2 = foo2;
n Khai báo tham chiếu tới
đối tượng
@ 2004 Trần Minh Châu. FOTECH. VNU 28
Làm việc với đối tượng
MyClass foo[10];
MyClass* foo2[10];
for (int i = 0; i < 10; i++) {
foo2[i] = new MyClass(i, i + 1);
}
n Tạo mảng các đối tượng
...
hoặc mảng các con trỏ
tới đối tượng
foo[7].PrintCount();
for (int i = 0; i < 10; i++)
{
foo[i].PrintCount();
}
n Truy nhập các đối tượng trong
mảng như vẫn làm đối với các
phần tử mảng thông thường
phải có constructor
mặc định để có thể
có khai báo này
@ 2004 Trần Minh Châu. FOTECH. VNU 29
Làm việc với đối tượng
class MyClass {
…
private:
// Instance of a class
MyOtherClass x;
// Pointer to an instance
// of a class
MyOtherClass* y;
};
n Có thể có thành viên là
các đối tượng thuộc lớp
khác.
(quan hệ chứa - “has-a”)
MyClass::MyClass {
this->y = new MyClass2();
}
MyClass::~MyClass {
delete this->y;
}
n Để tránh rò rỉ bộ nhớ, bất cứ
phần bộ nhớ nào được cấp phát
động tại constructor đều phải
được thu hồi tại destructor