- Dùng kiểu trả về là const T& để tránh modify nó trực tiếp (như kiểu gán nó). Tương tự với kiểu biến. Thường go tandem với object tạo bởi pointer. Ngược lại trả về value đi đôi với object thường. Lợi thế của trả về value là nó tạo object mới, không ảnh hưởng gì đến đầu vào cả (do khi nó trả về nó gọi copy constructor).
- Trả về Reference không có nghĩa là không immutable được. Ví dụ: copy assignment operator trả về reference nhưng hoạt động chẳng khác gì trả về value cả (chữ copy để nhấn mạnh tính immutable của nó).
- Nếu mà kiểu biển T&& thì nó thường gán với move semantics (move constructor, move assignment) dùng với những object được trả về mà chưa được gán).
- output của dereference *T cũng giống output của call function, trả về rvalue. Có thể dùng arithmethic operator để iterate nó (++, –, +/- number). Cũng có thể dùng static function std::prev, std::next để traverse.
- Generic của c++ lúc nào cũng có general typename keyword đi cùng. Nếu không thì dùng keyword class.
- using và typedef gần như tương tự nhau nhưng using mạnh và modern hơn (works với typename.)
- Để initialize struct thì làm như sau:
struct Point {
int x;
int y;
};
// C++98 and later
Point p1 = {10, 20};
// C++11 and later (uniform initialization)
Point p2{30, 40};
Designated Initializers (C++20)
Point p5 = {.x = 5, .y = 7};
Point p6{.x = 1, .y = 2};
//Partial Initialization
Point p10 = {10}; // x=10, y=0
- Struct cũng có constructor như bình thường, hình như nó mà implement constructor là mấy cái initialization ở trên lỗi luôn, được biệt là cái designated.
- override trong c++ là optional, nhưng khi thêm nó là phải khai báo function là virtual (mặc dù virtual vẫn hoạt động không cần override).
- Không thể define function trong function bình thường được mà phải define nó theo kiểu lambda. Có thể define struct bình thường trong hàm.
- typedef struct A {} A là old syntax của c, c++ cho phép khai báo biến sau definition nhưng nhìn xấu, không nên viết thế.
- size_t là số lượng phần tử nhiều nhất mà một array trong c++ cho phép chứa, do đó nó sẽ là unsign int. Hệ điều hành x32 thì nó là 4 bytes, x64 là 8 bytes.
- Để tránh nhiều headers include cùng một header thì:
#pragma once
// or
#ifndef A_H
#define A_H
...
#endif
- Nếu header A được included vào header B thì sau khi include B có thể dùng cả functions của A.
- std::forward để giữ lại thông tin của biến (lvalue hoặc rvalue) khi gọi hàm.
- std::remove_cvref để remove const, volatile, và ref (& và &&). Ngoài ra còn có std::remove_reference.
- constexpr là hàm có thể evaluate ở compile time.
- if constexpr chủ yếu hoạt động với type nếu dùng trong hàm. Còn constexpr chủ yếu hoạt động ngoài.
- Có thể dùng std::move để convert normal variables thành temporary variables T&&
- để một function có thể truy cập trực tiếp vào các private field, member functions của class, thì nên khai báo function đó là friend trong class đó. Chủ yếu dùng để overload operator<<. Có thể khai báo friend function trong class và định nghĩa nó bên ngoài hoặc khai báo và định nghĩa tất cả bên trong đều được.
- overload operator<< chỉ thực hiện được bên ngoài class do first argument không phải là this mà là std::ostream&. Chắc dùng static cũng được.
