int *a = newint; int *b = newint[10]; delete a; delete [] b;
const modifier & pointers
const u v: u is const
a b const c d: b is const
1 2 3 4 5 6
constint a; // a is const constint *b; // b points to a const variable int * const c; // c is a const pointer to an int variable. intconst * const d; // d is a const pointer to a const variable. int ** const; // a const pointer to a pointer to int
function overload
there can't be two functions with exactly same arguments.
conflicting definition:
int f(int a, int b); void f(int x, int y)
Example1:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
intincrease(int a, int delta){ return a + delta; } intincrease(int a, int& delta){ return a + delta; } intmain(){ int x = 4; increase(x, 4); // the first increase will be called because literal 4 can't be & increase(x, x); // compiler reported an error because it can't determine which function to call return0; }
Example2:
1 2 3 4 5 6 7 8 9 10 11
intincrease(int a, int& delta){ return a + delta; } intincrease(int a, constint& delta){ return a + delta; } intmain(){ int x = 4; increase(x, x); // call the first one, because x is not const increase(x, 4); // call the second one, because literal cannot be &. }
the last few arguments of a function can have default values.
1 2 3
intf(int a, int b = 1, int c = 2){ return a * b + c; }
note: this will cause overloading confict mentioned above.
Class
Access Permissions:
1 2 3 4 5
classClass { private: public: protected: };
Default Permission:
class: private
struct: public
Static Member
1 2 3 4 5 6
structPoint { staticint member; staticdoublefunction(){ member = 0; } };
Static Member: Point::member, static member doesn't
belong to any object.
Static Member Function: Can only access static
member and function args.
const modifer
1 2 3 4 5
structClass { voidfunc()const{ // const on (*this) ; } }
Constructor
1 2 3 4 5 6 7 8
structClass { int x, y; Class() = default; // delete this line and there won't be a constructor that takes 0 arg // Class() = delete; Class(int x, int y) : x(x), y(y) { } // x(x) means member x is constructed by arg x };
Usually constructors are public, otherwise you can't construct
outside.
Private
constructor & Singleton Design Pattern
1 2 3 4 5 6 7 8 9 10 11 12 13
structSingleton { private: Singleton() {} static Singleton* instance = NULL; public: static Singleton* getInstance(){ // only one Singleton can be constructed if (instance == NULL) instance = newSingleton(); return instance; } };
copy constructor
Copy Constructor: A constructor that takes an
argument, i.e. an instance of its type.
default copy constructor copies all members.
1 2 3 4 5 6 7 8 9 10 11 12 13
structMyString { char *arr; MyString(){ arr = newchar [100]; } // you can delete const modifier // but cannot delete & modifer, because it function arg without & will call a copy. MyString(const MyString &rhs) : String() { // default copy constructor will copy arr address // this constructor will new an char array and copy its value. int i; for(i = 0; rhs.arr[i]; ++i) arr[i] = rhs.arr[i]; arr[i] = 0; } }
cast constructor
Cast Constructor: a constructor that takes an argument, i.e. an
instance of other type
1 2 3 4 5
structType { int x, y; Type(int x) : x(x), y(0) { } }; Type t = 1; // this will only call Type(1)
classGeoDataHandler { // declarations private: Point arr[1001]; int len; int freq[100][100]; boolisin(Point p, int x1, int y1, int x2, int y2); public: GeoDataHandler(); voidappend(int x, int y); intquery(int x1, int y1, int x2, int y2); Point HH(); }; // implementations voidGeoDataHandler::append(int x, int y){ arr[len++] = Point(x, y); } intGeoDataHandler::query(int x1, int y1, int x2, int y2){ int counter = 0; for (int i = 0; i < len; i++) { if (arr[i].x >= x1 && arr[i].x <= x2 && arr[i].y >= y1 && arr[i].y <= y2) { counter++; freq[arr[i].x][arr[i].y]++; } } return counter; } Point GeoDataHandler::HH(){ int max = -1; Point res; for (int i = 0; i < 100; i++) for (int j = 0; j < 100; j++) if (max < freq[i][j]) {max = freq[i][j]; res = Point(i, j);} return res; }
An declared but not implemented function will not cause
compile error,
and sometimes causes error when linking.
mutable modifier
a mutable member can be modified when this object is const.
classGeoDataHandler { private: Point arr[1001]; int len; mutableint freq[100][100]; public: intquery(int x1, int y1, int x2, int y2)const{ // const *this int counter = 0; for (int i = 0; i < len; i++) { if (arr[i].x >= x1 && arr[i].x <= x2 && arr[i].y >= y1 && arr[i].y <= y2) { counter++; freq[arr[i].x][arr[i].y]++; // modify mutable member! } } return counter; } };
structPair { int x; mutableint y; // a key with a mutable value booloperator < (const Pair __) const { return x < __.x; } }; std::set <Pair> st; st.insert((Pair){0, 1}); auto it = st.begin(); // returns a const iterator. it -> y++; // ok it -> x++; // can not modify x
friend
friend given a class/function the same access to this class.
1 2 3 4 5 6
classA{ private: int x, y; friendclassB; // B's member can access A's private member x, y friendvoidC::func(); // C's member function func can access A };
overloading operators
a + b:
as member: Type Type :: operator + (Type b);, where
this points to a.
as normal function:
Type operator + (Type a, Type b);
operator as member cannot be declared outside class declaration.
1 2 3 4 5 6 7 8 9 10 11 12
classType { int x; public: Type(int x): x(x) { } Type operator + (const Type rhs) const { return x + rhs.x; } // x is private, should be declared as friend friend Type operator * (Type a, Type b) const { return a.x + b.x; } };
template <typename T = int, int size = 100> // default template , can be called by Type <> x; class Type { T x, y, arr[size]; Type():x(0),y(0) { } voidadd(); friendclassB<T>; }; template <typename T> void Type<T>::add() { return x + y; } template <> classType <> { ; }
含 template 的声明与定义分散在不同的 cpp
文件中,会导致链接期间无法找到对应函数。
正确的做法是在 .h 中声明,在 .cpp 中实现。
inheritance
1 2 3 4 5 6 7
template<classT> classDArrayDel : public DArray<T> { };
classDoubleDArray : public DArray<double> { };
template<classT1, classT2> classMixedDArray : public DArray<T1> { };