system: You are a trustworthy AI assistant. Your task is to answer the question honestly and not fabricate information.

user: Can you provide information about Cú pháp ngôn ngữ C++ from the encyclopedia?, in Vietnamese language

assistant: Cú pháp ngôn ngữ C++ là tập hợp các quy 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++.
Chức năng Hướng đối tượng.
Lớp.
Đị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.
 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 codice_1 và codice_2 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").
Định nghĩa lớp con.
 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
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)
Khai báo một biến đối tượng.
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ỏ
 &amp;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 &lt;iostream&gt;
 using namespace str;
 class Number
 private:
 int x;
 public:
 int main ()
 Number myNumber;
 myNumber.setValue(4);
 myNumber.getValue();
 return 0;
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ụ)
Các thành viên của lớp.
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:
 const int x; 
 #include &lt;iostream&gt;
 #include &lt;string&gt;
 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 getPrivate() const;
 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 hàm 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à:
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 codice_17 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 codice_18 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.
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:
[virtual] int
Hàm dựng (còn gọi là cấu tử, Constructor).
Cấu tử là hàm thành viên đặc biệt, có tên trùng với tên của lớp, làm nhiệm vụ tạo lập đối tượng theo yêu cầu. Khi một đối tượng được khai báo thì cấu tử sẽ tự động thực hiện để tạo lập đối tượng trong bộ nhớ. Một lớp có thể có nhiều cấu tử (tải bội), cấu tử không có tham số là cấu tử mặc định. Nếu ta không định nghĩa một cấu tử nào thì cấu tử mặc định sẽ được sử dụng, trái lại sẽ không được sử dụng.
 class Point 
 { int x, y;
 public:
 Point(){x=0;y=0;} //Cấu tử mặc định
 void Display(){cout «"Toa do: ("«x«','«y«')'«endl};
int main()
 a.Display();b.Display();c.Display();
 return 0;
 
Đối tượng a được tạo lập bởi cấu tử thứ nhất. Các đối tượng b và c được tạo lập bởi cấu tử thứ hai. Cấu tử thứ hai có một tham số mặc định, nếu ta đặt mặc định cho cả hai tham số thì phải bỏ đi cấu tử thứ nhất, vì nếu không, sẽ dẫn đến sự nhập nhằng khi khai báo Point a; (Ambiguity between 'Point::Point()' and 'Point::Point(int,int)').
 () 18:16, ngày 28 tháng 9 năm 2009 (UTC)
Hàm hủy (còn gọi là huỷ tử, destructor).
Khi đối tượng không còn được sử dụng thì nên giải phóng nó khỏi bộ nhớ. Các hủy tử được sử dụng để làm việc này. Hủy tử cũng là hàm thành viên có tên trùng với tên của lớp, nhưng có thêm ký tự ~ ở trước. Nếu ta không định nghĩa, thì sử dụng hủy tử mặc định.Tất cả các hủy tử đều không có tham số. Trong ví dụ trên, ta có thể định nghĩa hủy tử như sau:
 () 18:15, ngày 28 tháng 9 năm 2009 (UTC)
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 đượ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 codice_13 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 &amp; How và Const correctness về cách sử dụng từ khóa codice_13 cho có hiệu quả)
Hàm ảo (virtual function).
Hàm ảo thường được định nghĩa ở lớp cơ sở và cho phép các lớp dẫn xuất từ nó được định nghĩa lại hàm ảo này. Giả sử FIGURE là lớp cơ sở, có sẵn phương thức Draw(). Lớp SQUARE và lớp CIRCLE cùng được dẫn xuất từ lớp FIGURE. Tất nhiên ta sẽ phải định nghĩa lại hai phương thức là SQUARE::Draw() và CIRCLE::Draw() của từng lớp cho phù hợp. Giả sử ptr là con trỏ trỏ đối tượng thuộc lớp FIGURE, s và c tương ứng là hai đối tượng thuộc lớp SQUARE và CIRCLE. Ta muốn rằng, khi cho ptr trỏ tới s thì lời gọi prt-&gt;Draw() sẽ vẽ ra hình vuông, còn khi cho ptr trỏ tới c thì lời gọi prt-&gt;Draw() sẽ vẽ ra hình tròn. Cách giải quyết của C++ là định nghĩa FIGURE::Draw() là hàm ảo. Ta xem ví dụ sau:
class FIGURE 
 { int Xc, Yc;
 public:
class CIRCLE:public FIGURE
 { int R;
 public:
 void Draw()
 { cout «"Ve hinh Tron:"«endl;
 FIGURE::Draw();
 cout«"Ban kinh: "«R«endl;
 };
class SQUARE:public FIGURE
 { int D; 
 public:
 void Draw()
 { cout «"Ve hinh Vuong:"«endl;
 FIGURE::Draw();
 cout«"Do dai canh: "«D«endl;
 };
int main()
 CIRCLE c(30,30,50);
 FIGURE *ptr; 
 ptr=&amp;s; ptr-&gt;Draw();
 ptr=&amp;c; ptr-&gt;Draw();
 getch();
 return 0;
 
Không thể định nghĩa cấu tử là hàm ảo, vì chính cấu tử làm nhiệm vụ khởi tạo bảng phương thức ảo VMT (Virtual Methods Table). 
Tuy nhiên các hủy tử có thể là hàm ảo.
Hàm cơ bản trừu tượng (pure virtual function).
Hàm cơ bản trừu tượng được giới thiệu trong lớp nhưng không được định nghĩa; hàm này bắt buộc phải được định nghĩa lại trong lớp con (derived class).
Nguyên tắc viết một hàm cơ bản trừu tượng là thêm =0 khi giới thiệu hàm.
Thí du:
Chức năng đặc biệt trên các hàm trong C++.
codice_22.
Hàm bạn không phải là hàm thành viên của lớp nhưng có thể thay đổi giá trị thành viên của lớp. Thí dụ:
Nạp chồng hàm (function overloading).
Trong C++ có thể định nghĩa nhiều hàm trùng tên nhau, nhưng những hàm này phải có parameter khác nhau.
Thí dụ:
// Hàm này nhận 1 tham số là: "ia"
int ham (int ia)
 return ia; 
// Hàm này cùng tên với hàm trên và nhận 2 tham số là: "ia" và "ib"
int ham (int ia, int ib)
 return ia + ib;
Nạp chồng toán tử (operator overloading).
Nạp chồng toán tử cho phép định nghĩa lại một toán tử (thí dụ định nghĩa lại +, -, *, /, vân vân) cho một type định nghĩa bởi người dùng.
Thí dụ: