Cú pháp ngôn ngữ C++
Bách khoa toàn thư mở Wikipedia
|
Cú pháp ngôn ngữ C++ là tập hợp các qui tắc nhằm xác định cách thức viết và dịch trong ngôn ngữ lập trình C++.
Vì C++ là ngôn ngữ được thiết kế để có thể hoạt động tương thích với ngôn ngữ C nên hai ngôn ngữ này chia sẻ nhau nhiều điểm chung trong cú pháp. Đối với các cấu trúc câu lệnh thông thường, các hàm, biến, và kiểu dữ liệu cơ bản xin xem thêm bài cú pháp C. Bài này chỉ tập trung vào các chủ đề căn bản mà ngôn ngữ C không có trong đó bao gồm việc hỗ trợ các mẫu hình lập trình tiêu bản và lập trình hướng đối tượng của C++.
[sửa] Chức năng Hướng đối tượng
[sửa] Lớp
[sửa] Định nghĩa lớp cơ bản
Việc sử dụng lớp trong một chương trình C++ có hai phần chính là phần định nghĩa lớp và phần khai báo và truy cập các thành viên của một đối tượng có kiểu là một lớp cho trước.
- Định nghĩa thông thường của một lớp cơ bản không kế thừa từ bất kì lớp nào khác:
class myClass // tên lớp { public: (danh sách các thành viên có đặc tính công cộng) private: (danh sách các thành viên có đặc tính riêng tư) protected: (danh sách các thành viên có đặc tính bảo tồn) }; // dấu chấm phẩy chấm dứt câu lệnh
Lưu ý: khi các từ khoá đặc tính public:, private:
và protected:
không có mặt thì toàn bộ các thành viên của lớp sẽ được hiểu mặc định là có đặc tính riêng tư (private).
- Dùng khai báo biến
myVar
làm một thực thể (instance) của lớp myClass:
[sửa] Định nghĩa lớp con
- Định nghĩa thông thường của một lớp con kế thừa từ lớp
myClass
. Trong thí dụ dưới đây thì[đặc_tính]
có thể thay bằng một trong ba từ khoá đặc tínhpublic:, private:
vàprotected:
hoặc nếu bỏ qua không viết ra thì đặc tính kế thừa mặc định của lớp con sẽ là "riêng tư".
class mySubClass : [đặc_tính] myClass { public: (danh sách các thành viên có đặc tính công cộng) private: (danh sách các thành viên có đặc tính riêng tư) protected: (danh sách các thành viên có đặc tính bảo tồn) }; // dấu chấm phẩy chấm dứt câu lệnh
- Định nghĩa thông thường của một lớp con kế thừa từ hai lớp
myClass1
vàmyClass2
. Tương tự trên,[đặc_tính]
có thể thay bằng một trong ba từ khoá đặc tínhpublic:, private:
vàprotected:
hoặc nếu bỏ qua không viết ra thì đặc tính kế thưà mặc định của lớp con sẽ là "riêng tư".
class mySubClass : [đăc_tính] myClass1, [đăc_tính] myClass2 { public: (danh sách các thành viên có đặc tính công cộng) private: (danh sách các thành viên có đặc tính riêng tư) protected: (danh sách các thành viên có đặc tính bảo tồn) }; // dấu chấm phẩy chấm dứt câu lệnh
[sửa] Khai báo một biến đối tượng
[sửa] Biến đối tượng thông thường
Biến đối tượng có thể khai báo hay đôi khi còn gọi là thực thể hoá tùy theo cách xây dựng lớp của người lập trình. Thường quá trình xác lập này được tiến hành thông qua các hàm dựng. Dĩ nhiên, người ta có thể dùng ngay cả các phương thức thường dùng như là dùng tham chiếu (tức là dùng định nghĩa con trỏ), dùng mảng, dùng cấu trúc, hay phức tạp hơn (mảng tham chiếu chẳng hạn) để khai báo một biến đối tượng. (Xem thêm Cú pháp ngôn ngữ C.) Trong mọi trường hợp này thì kiểu của biến đối tượng được xem là lớp mà nó khai báo. Thí dụ:
myClass A10; //biến thông thường myClass *A10ptr = new myClasss; //biến con trỏ &myClassRef = A10; //biến kiểu tham chiếu (ngược)
Lưu ý: người lập trình hoàn toàn có thể thực thể hoá một biến đối tượng mà không cần phải xây dựng một hàm dựng, trình dịch sẽ tự tạo ra một "hàm dựng mặc định". Tuy nhiên, một khi đã xây dựng bất kì một hàm dựng nào thì cách khai báo mặc định này sẽ không còn được trình dịch chấp thuận và sẽ báo lỗi. Thí dụ sau đây thể hiện cách tạo một lớp mà không cần hàm dựng:
#include <iostream> using namespace str; class number { private: int x; public: void setValue (int y) { x= y;} void getValue () {cout << x << endl;} }; main () { number myNumber; myNumber.setValue(4); myNumber.getValue(); }
[sửa] Biến đối tượng là một hằng
Trường hợp khi thành lập một đối tượng hằng thì việc điều chỉnh trạng thái nội tại của nó là không hợp lệ do đó, chỉ có một cách duy nhất là gán cho nó một bộ giá trị (hay một trạng thái) ban đầu. Trong trường hợp này thì sau khi đã thực thể hóa, biến đối tượng chỉ có thể cho phép đọc các giá trị nào mà lớp tạo ra nó cho phép. (xem thí dụ)
[sửa] Các thành viên của lớp
[sửa] Thành viên dữ liệu
Ngoài các khai cáo thành viên có kiểu dữ liệu như thông thường trong C, thì người lập trình còn có thể khai báo nó như một hằng, hay như một biến tĩnh, hay có cả hai đặc tính:
- Thành viên dữ liệu là một hằng: Trương tự như trong C, một thành viên là dữ liệu có thể được khai báo như là một hằng bởi từ khóa
const
đứng trước tên kiểu dữ liệu. Một khi đã khai báo là hằng thì không thể gán giá trị mới hay thay đổi nội dung của kiểu dữ liệu đó nữa (Lưu ý: trong C++ thì kiểu dữ liệu có thể là một lớp đã được định nghiã). Do đó, dữ liệu là hằng sẽ được gán giá trị ban đầu ngay trong dòng lệnh khai báo tên của nó:
const int x;
- Thành viên dữ liệu có kiểu
static
: Một khi thành viên của một lớp có kiểu làstatic
thì nó sẽ có giá trị tĩnh cho mọi thực thể của cùng một lớp. Nghĩa là sự thay đổi giá trị của thành viên tĩnh này trong một thực thể bất kì sẽ có hiệu quả thay đổi của cùng thành viên đó trong các thực thể khác của cùng một một lớp. Thực tế, khi một thành viên của một lớp được khai báo tĩnh thì phần bộ nhớ chứa giá trị của thành viên này sẽ được chia sẽ cho mọi thực thể về sau. Nói cách khác, ứng với mỗi thành viên tĩnh, chỉ có duy nhất một giá trị chia sẽ chung cho cả lớp.
- Thành viên dữ liệu có thể có cả hai đặc tính trên tức là vừa có kiểu tĩnh vừa là hằng số. Thường từ khóa
static
được viết trước sau đó là từ khóaconst
. Thí dụ dưới đây minh họa các cú pháp khai báo. việc sử dụng một biến hằng có kiểu tĩnh rất tiện lợi cho nhiều đối tượng thực thể hóa có cùng một lớp chia sẽ chung một hằng số (thí dụ: hằng số Pi dùng chung cho các đối tượng cung tròn, đường tròn, và elipse). Ngược lại, khi có các hằng số đặc thù cho từng thực thể của một lớp thì một cách là dùng hằng số thông thường (chẳng hạn như cùng một lớp "chiết tính tiền lời cho vay" nhưng thực thể ngắn hạn có "hằng số lãi kép" cao hơn nhiều so với hằng số lãi kép dài hạn). Thí dụ dưới đây minh họa cú pháp khai báo
#include <iostream> #include <string> using namespace std; class A { public: A(int x, int y); void setStatic (int x) { value= x; } //hàm thành viên xác lập trực tiếp trong dòng lệnh khai báo void setNormal (int x) { normal=x; } void getValue() const { cout<< "value "<< value << endl;} void getShareConst() const {cout << "shareconst :" << shareconst << endl;} void getPrivate() const; void getNormal() const {cout << "normal variable :" << normal << endl;} private: static int value; static const int shareconst; const int privateconst; int normal; }; int A::value=3; //gán giá trị cho biến tĩnh ở đây dùng chung cho mọi biến của lớp A (=3) const int A::shareconst=2; //gán giá trị cho hằng có kiểu tĩnh A::A(int x, int y):privateconst(y) //Hàm dựng: cách gán giá trị ban đầu cho một hằng thông thường { normal=x; //gán giá trị ban đầu cho biến thông thường } void A::getPrivate() const //cách để xác lập mã cho hàm thành viên bên ngoài dòng lệnh khai báo của lớp { cout <<"privateconst :" << privateconst << endl; } int main () { A A1(3,1); // giá trị hằng privateconst của A1 được gán ở đây (=1) A A2(5,2); // giá trị hằng privateconst của A2 được gán ở đây (=2) A1.getPrivate(); A2.getPrivate(); A1.getShareConst(); //đọc giá trị hằng của biến tĩnh trong A1 A2.getShareConst(); //biến tĩnh trong A2 có cùng giá trị với biến tĩnh của A1 A1.setValue(4); //cài đặt cho biến tĩnh value cho đối tượng A1 A2.getValue(); //Cài dặt từ A1 nhưng lại có giá trị luôn cho đối tượng A2 return 0; }
Kết quả sau khi dịch và chạy chương trình trên là:
1 2 3 3 4
Lưu ý: bạn sẽ không thể gán giá trị nào khác ngoài các giá trị ban đầu khi khai báo cho các hằng. Trong thí dụ trên hàm setValue sẽ cho phép bạn gán lại giá trị tĩnh value
của lớp A và nó ảnh hưởng đến mọi thực thể cùng lớp A. Trong khi hàm setNormal cho phép gán lại giá trị cho biến normal
thông thường trong một thực thể của lớp A sẽ chỉ hiệu lực cho riêng thực thể đó mà thôi.
[sửa] Hàm thành viên
Các khai báo một thành viên là hàm trong một lớp có thể dùng hai dạng chính sau:
- Mô tả trực tiếp trong định nghiã của lớp mà hàm là thành viên
[virtual] int
- Mô tả sau bên ngoài sau định nghĩa của lớp mà hàm là thành viên
[sửa] Hàm dựng
- Không dùng đến các hàm khác
- Sử dụng các hàm khác để gọi
[sửa] Hàm hủy
[sửa] Hàm hằng
Một hàm thành viên có thể được khai báo đẻ trở thành hàm hằng. Với khai báo này thì thành viên đó sẽ chỉ có giá trị đọc đuợc mà không có hiệu lực thay đổi giá trị nội tại của một thực thể. Để khai báo thì từ khóa const
phải được đặt ngay sau khai báo hàm và đứng trước khối mã xác lập hàm số đó nếu có.
Lưu ý: Trong trường hợp này thì hàm hằng được hiểu với ý nghĩa khác với ý nghĩa trong toán học (khi một hàm số là có giá trị không đổi)
// hàm hằng class Time { public: Time(int h, int m, int s); int getHour() const; //Hàm hằng chỉ đọc được void setHour(int h); // hàm này dùng để gán hay thay đổi giá trị nên không thể khai báo const private: int hour; }; int Time::getHour() const //khai báo hàm hằng { return hour; // không thay đổi giá trị của bất kì thành viên nào } void Date::setHour(int h) { hour = h; // thay đổi giá trị của thành viên dữ liệu } int main() { Time MyTime(10,5,15); const Time MyNoon(12,0,0); // Khai báo một đối tượng (hay một thực thể) là hằng MyTime.setHour(5); // OK Mytime.getHour(); // OK // MyNoon.setHour(2); // lỗi dòng này vì việc cài giá trị mới lên hằng MyNoon }
Lưu ý: Việc khai báo một kiểu dữ liệu nói chung hay một thành viên của một lớp nói riêng là một hằng có thể có nhiều điểm phức tạp khi kết hợp với các kiểu tham chiếu hay con trỏ. (xem thêm Const Correctness in C++, The C++ 'const' Declaration: Why & How và en:Const correctness về cách sử dụng từ khóa const
cho có hiệu quả)
[sửa] Hàm ảo
[sửa] Hàm cơ bản trừu tượng (không có nội dung)
[sửa] Hàm thành viên có kiểu static
[sửa] Chức năng đặc biệt trên các hàm trong C++
[sửa] friend
[sửa] Quá tải hàm
[sửa] Quá tải toán tử
[sửa] Chức năng Tiêu bản
[sửa] Tiêu bản đơn giản
[sửa] Tiêu bản phức hợp
[sửa] Sử dụng STL
[sửa] Trình bày mã xác lập nội dung một chương trình C++
[sửa] Xem thêm
- Lập trình hướng đối tượng
- C++
- Cú pháp ngôn ngữ C
- Thư viện chuẩn C++
- Thư viện chuẩn C
- en:Const correctness
[sửa] Tham khảo
- Const Correctness in C++
- MSDN2 Library
- Trình dịch GNU g++ của các hệ điều hành SUSE SLES Linux 9.2 và RedHat Linux 7.3 --dùng trong việc kiểm nghiệm lại các cấu trúc văn phong theo các tiêu chuẩn.