C++ Coding Standard - V2
C++ Coding Standard - V2
Version 2
Contents
I. Giới thiệu ............................................................................................................................................... 3
II. Coding convention................................................................................................................................. 3
1. Các phong cách đặt tên phổ biến ...................................................................................................... 3
2. Quy tắc đặt tên class ......................................................................................................................... 3
3. Quy tắc về đặt tên biến, tên hàm/method ....................................................................................... 4
4. Quy tắc đặt tên enum và định nghĩa các giá trị hằng số .................................................................... 5
5. Quy tắc khai báo struct ...................................................................................................................... 5
6. Quy tắc đối với const và reference keyword ..................................................................................... 5
7. Thụt đầu hàng và cách khoảng .......................................................................................................... 6
8. Một vài tiêu chí khác về coding style ................................................................................................ 6
9. Comment source code ....................................................................................................................... 6
10. Comment cho method/hàm đối với các dự án tạo mới. ................................................................. 6
11. Các ngôn ngữ khác như SQL hoặc xml thuộc string của code. ..................................................... 6
12. Về format, bố trí thứ tự trong source code. ................................................................................... 7
13. Dùng switch đối với các kiểu dữ liệu enumerable ........................................................................ 7
14. Thêm TODO Comment vào các vị trí chưa hoàn thành. ............................................................... 8
15. Tối giản các câu lệnh if ................................................................................................................. 8
16. Loại bỏ các câu lệnh if không cần thiết ......................................................................................... 9
17. Có new thì phải có delete, có malloc thì phải có free.................................................................... 9
18. Có open thì phải có close .............................................................................................................. 9
19. Không nên hard-code các magic number .................................................................................... 10
20. Không lạm dụng biến global ....................................................................................................... 10
21. Sử dụng biến local nếu có thể...................................................................................................... 10
22. Cần khởi tạo biến đã khai báo. .................................................................................................... 10
23. Hạn chế viết function quá dài và các điều kiện lồng nhau nhiều. ............................................... 10
24. Header file (*.h) .......................................................................................................................... 10
1
25. Không gộp nhiều class trong 1 file .............................................................................................. 11
26. Không sử dụng goto label............................................................................................................ 11
27. Sử dụng this-> và classname:: ..................................................................................................... 11
III. Các lỗi thường gặp........................................................................................................................... 11
1. Thừa/thiếu điều kiện ........................................................................................................................ 11
2. Khai báo biến nhưng không sử dụng ............................................................................................... 12
3. Thiếu xử lý return, default trong switch case .................................................................................. 12
4. Không quan tâm đến warning của compiler .................................................................................... 12
5. Trùng tên biến trong nested for ....................................................................................................... 12
6. Viết code dài dòng, không cần thiết ................................................................................................ 12
7. Copy lại code hoặc comment code nhưng quên không edit ............................................................ 13
8. 2 hàm làm chức năng tương tự nhưng format không thống nhất: ................................................... 13
9. Xử lý không tối ưu: ......................................................................................................................... 13
10. Không define const mà hardcode. ............................................................................................... 14
11. Include và using namespace nhưng không sử dụng .................................................................... 14
12. Đã dùng "using namespace std;", nhưng vẫn gọi "std::" ............................................................. 14
13. Sử dụng == true là không cần thiết: ............................................................................................ 14
14. Dấu {} không thống nhất............................................................................................................. 15
15. Không nên chia ra giữa việc khai báo biến, khởi tạo và nhập giá trị .......................................... 15
16. Chia cho giá trị 0 ......................................................................................................................... 15
17. Sử dụng đường dẫn tuyệt đối trong code..................................................................................... 15
18. Sử dụng pointer không đúng ....................................................................................................... 15
2
I. Giới thiệu
Tài liệu này sẽ định nghĩa các quy tắc nhằm nâng cao chất lượng của C++ code
dựa trên các chuẩn chung nhất. Các quy tắc sẽ phù hợp nhất với ISO C++
Language sử dụng phương pháp lập trình OOP.
Mục đích của tài liệu này nhằm để giúp cho developer có thể tạo ra các project có
khả năng maintain dễ dàng, đồng thời giảm thiểu tối đa các vấn đề do project sử
dụng nhiều compiler, được viết bởi nhiều developer với mỗi phong cách lập trình
khác nhau.
Kiểu Mô tả Ví dụ
Pascal Viết hoa chữ cái đầu tiên của mỗi từ. PascalCase
Camel Viết thường chữ cái đầu của từ đầu camelCase
tiên. Các từ còn lại viết hoa chữ cái
đầu.
Uppercase In hoa toàn bộ tên UPPERCASE
Hungarian Notation Gồm phần tiền tố chỉ kiểu dữ liệu iTuSo, strName
hoặc đặc trưng của biến và phần tên
với mỗi từ được bắt đầu bằng chữ in
hoa.
3
3. Quy tắc về đặt tên biến, tên hàm/method
1. Đặt tên biến sử dụng style là Hungarian Notation (gồm phần tiền tố chỉ kiểu dữ
liệu hoặc đặc trưng của biến và phần tên với mỗi từ được bắt đầu bằng chữ in
hoa).
Ví dụ: string strMacAddress;
2. Đặt tên hàm/method sử dụng style là Camel-case (từ đầu tiên sẽ viết thường, kể
từ từ thứ 2 thì ký tự đầu tiên của từ sẽ viết hoa).
Ví dụ: Customer getCustomerInfo();
3. Đặt tên biến, tên hàm/method thể hiện được ý nghĩa sử dụng.
Ví dụ: char szIpAddress[64];
4. Không nên viết tắt trong tên biến, tên hàm/method (ngoại trừ trường hợp là các
từ viết tắt có nghĩa, và cần có tài liệu thống kê các từ viết tắt).
5. Tên hàm/method cần thể hiện được hành động mà hàm/method sẽ thực hiện.
Ví dụ: Customer getCustomerInfo(); hoặc bool parseIpAddress(…);
6. Đặt tên method mang tính đối tượng hóa
Ví dụ: Trong class Customer thì chỉ cần đặt tên method là getInfo() thay vì
getCustomerInfo().
7. Tiền tố của tên biến local sẽ đặt theo style Hungarian Notation như sau:
bool sẽ có tiền tố là b, ví dụ: bool bResult;
int sẽ có tiền tố là i, ví dụ: int iCount;
long sẽ có tiền tố là l, ví dụ: long lSize;
float sẽ có tiền tố là f, ví dụ: float fRatio;
char sẽ có tiền tố là c, ví dụ: char cKey;
đối với chuỗi cơ bản sẽ có tiền tố là sz, ví dụ: char szIp6Address[64];
string sẽ có tiền tố là str, ví dụ: string strAddress;
enum sẽ có tiền tố là e, ví dụ: State eInstallState;
pointer sẽ có tiền tố là p, ví dụ: char* pBuffer;
8. Đối với tham số, có thể không cần đặt tiền tố như biến local nêu trên, nhưng
cần thống nhất cho toàn project.
9. Đối với biến global cần thêm tiền tố g_ so với quy định biến local nêu trên, ví
dụ: int g_iFlow = 0;
10. Đối với biến member của class sẽ thêm tiền tố _ so với quy định biến local nêu
trên, ví dụ: int _iFlow = 0;
Lưu ý: Đối với một số project viết trên nền tảng Windows thì biến member của
class sẽ thêm tiền tố là m_. Ví dụ: int m_iFlow = 0;
11. Đối với kiểu dữ liệu pointer thì khai báo theo format như sau:
char* pBuffer; hoặc int* pNeeded;
4
4. Quy tắc đặt tên enum và định nghĩa các giá trị hằng số
1. Tên enum và các giá trị của enum phải thể hiện được ý nghĩa sử dụng, tương tự
với tên hằng số.
2. Tên enum sử dụng style là Pascal-case và các giá trị của enum sử dụng là
Uppercase (viết hoa toàn bộ đối với các giá trị của enum, các từ phân cách bởi
dấu gạch dưới).
Ví dụ:
enum Color
{
RED = 1,
GREEN = 2,
BLUE = 3
};
3. Tên hằng số sử dụng style là Uppercase (viết hoa toàn bộ đối với tên hằng số,
các từ phân cách bởi dấu gạch dưới).
Ví dụ:
const size_t PAGE_SIZE = 8192;
Ví dụ:
typedef struct _STRUCTNAME
{
int StructMember1;
int StructMember2;
std::string StructMember3;
} STRUCTNAME, *PSTRUCTNAME;
5
4. Đối với tham số là kiểu dữ liệu là object, struct, string truyền vào method/hàm
thì khai báo như sau:
Customer compare(const Customer& other);
Customer compare(const Customer& other) const;
2. Sử dụng cặp dấu { } để đánh dấu một khối mã nguồn. Nên thống nhất một cách
sử dụng cặp dấu {} trong suốt project. Trong các lệnh if, for, ... nếu chỉ có một
lệnh thì có thể không cần đánh dấu khối mã nguồn.
3. Đối với điều kiện if giá trị Boolean thì không cần có toán tử so sánh. Ví dụ:
if(SUCCEEDED(hr)) {…}, if(bProcessing) {…}
11.Các ngôn ngữ khác như SQL hoặc xml thuộc string của code.
Cần viết để dễ hiểu, dễ maintain, và tuân theo standard của ngôn ngữ đó.
Ví dụ về format xml trong chuỗi như sau:
const char* szXml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
6
"<root>"
"<device>"
"<model>%s</model>"
"<mac>"
"<string>%s</string>"
"<value>%s</value>"
"</mac>"
"<node_name>"
"<string>%s</string>"
"</node_name>"
"</device>"
"</root>";
Ví dụ về format SQL trong chuỗi như sau:
const char* szSql = "SELECT "
"Id, "
"FullName, "
"Address, "
"PhoneNumber, "
"Profile "
"FROM Customer "
"WHERE Id > 500 ";
7
//TODO: Do something
}
14. Thêm TODO Comment vào các vị trí chưa hoàn thành.
Các vị trí sẽ TODO comment gồm có:
1. Các phần source code cần implement nhưng chưa implement
2. Các phần source code cần phải xem xét lại về việc implement
3. Các method cần phải implement nhưng chưa implement
4. Các method mà không implement (empty method)
8
{
fProportion = 1;
}
9
– Nếu open ở contructor thì sẽ close ở destructor, nếu viết hàm để open thì
cần có hàm để close.
– Không nên open ở một module và close ở một module khác.
23. Hạn chế viết function quá dài và các điều kiện lồng nhau nhiều.
Đối với một function quá dài và các điều kiện lồng nhau quá nhiều sẽ là một thử
thách lớn đối với việc maintain. Vì thế cần chia nhỏ function và không sử dụng các
điều kiện lồng nhau trong khi viết code.
10
- Đối với Microsoft C++ (Visual C++) thì có thể dùng quy tắc sau ở đầu header
file.
#pragma once
- Không sử dụng #include trong file *.h nếu không thật sự cần thiết.
- Không sử dụng using namespace trong file *.h nếu không thật sự cần thiết.
11
Để không xảy ra hiện tượng check thừa thiếu, thì cần validate data trước khi sử
dụng.
2. Khai báo biến nhưng không sử dụng
void MyFunction()
{
std::string strComponents;
}
12
iPosition = iLeft;
iPosition += iWidth;
Ví dụ 2:
//Không nên viết như sau:
std::string strFilePath = strHomePath;
strFilePath += PLUGIN_IO_FILE_PATH;
7. Copy lại code hoặc comment code nhưng quên không edit
Ví dụ :
// Sai:
string strStudentName; // Name of Student
string strStudentAddress ; // Name of Student
// Đúng:
string strStudentName; // Name of Student
string strStudentAddress ; // Address of Student
8. 2 hàm làm chức năng tương tự nhưng format không thống nhất:
Ví dụ:
// Không nên viết như sau
JobIDs getRecoverableRootJobIDs();
void getPausedRootJobIDs(JobIDs jobIDs);
//Chỉ cần gọi lệnh sau thay cho đoạn code trên
jobMap.clear();
13
Ví dụ 2: Khi 1 hàm dài khoảng 100 line (lớn hơn 1 page màn hình) xử lý chung
cho cả 2 trường hợp success và error thì nên tách thành 2 hàm riêng biệt: 1 hàm xử
lý trường hợp success và 1 hàm xử lý trường hợp error. Ví dụ:
void writeFile();
// Tách thành 2 hàm:
void writeFileSuccess();
void writeFileError();
14
14. Dấu {} không thống nhất
Ví dụ, như sau là không thống nhất :
if (bFlag) {
...
}
if (iNum > 1)
{
...
}
15. Không nên chia ra giữa việc khai báo biến, khởi tạo và nhập giá trị
Ví dụ:
CTestClass *testClass = 0;
testClass = getInstanceTestClass();
15
THAM KHẢO
16