Reference:
http://www.cplusplus.com/doc/tutorial/classes/
http://www.cplusplus.com/doc/tutorial/templates/
Basic
Class는 컨테이너 같은 느낌으로 내부에 variable, function들을 넣어서 한번에 관리하는 것.
내부에 private / public이 있는데 사실 첨에는 왜 private이 필요한가 생각할 수도 있겠지만, 큰 프로젝트에서는 실수로 다른 사람이나 function이 private data를 건들지 않게 하기 위한 것.
<Example 1>
class Rectangle { int width, height; public: void set_values (int,int); int area (void); } rect; |
여기서 width랑 height는 private 이며, 클래스 외부에서 접근이 불가능하다. 즉 클래스 내부에 선언된 함수를 사용해서만 데이터를 변경할 수 있다.
set_values와 area는 직접 사용할 수 있는 function이다.
<Example 2>
// classes example #include using namespace std;
class Rectangle { int width, height; public: void set_values (int,int); int area() {return width*height;} };
void Rectangle::set_values (int x, int y) { width = x; height = y; }
int main () { Rectangle rect; rect.set_values (3,4); cout << "area: " << rect.area(); return 0; } |
결과는
Constructors
얘는 첨에 클래스 선언을 할 때, 자동으로 데이터를 initialize 해줄 수 있도록 하는 것이다.
<Example 3>
// example: class constructor #include using namespace std;
class Rectangle { int width, height; public: Rectangle (int,int); int area () {return (width*height);} };
Rectangle::Rectangle (int a, int b) { width = a; height = b; }
int main () { Rectangle rect (3,4); Rectangle rectb (5,6); cout << "rect area: " << rect.area() << endl; cout << "rectb area: " << rectb.area() << endl; return 0; } |
rect area: 12 rectb area: 25 |
얘는 클래스 내부에 Rectangle이라는 Class이름과 동일한 이름을 가지는 함수를 선언하고, 이 함수는 return 값도 존재하지 않는다. 왜냐하면 init을 위한 것이기 때문에.
그래서 밑에 main function에서 보면 Rectangle rect (3, 4)라고 되어있는데, 그러면 클래스 선언과 동시에 width, height가 초기화된다.
Overloading constructors
다른 함수들과 마찬가지로, 얘도 argv를 조절함으로써 같은 이름으로 다른 함수들을 지정할 수 있다.
<Example 4>
// overloading class constructors #include using namespace std;
class Rectangle { int width, height; public: Rectangle (); Rectangle (int,int); int area (void) {return (width*height);} };
Rectangle::Rectangle () { width = 5; height = 5; }
Rectangle::Rectangle (int a, int b) { width = a; height = b; }
int main () { Rectangle rect (3,4); Rectangle rectb; cout << "rect area: " << rect.area() << endl; cout << "rectb area: " << rectb.area() << endl; return 0; } |
rect area: 12 rectb area: 25 |
rect는 argv로 3, 4가 들어갔기 때문에 width와 height가 3, 4로 설정되었고,
rectb는 argv가 없기 때문에 argv가 없는 function 내부의 init value인 5, 5로 설정되었다.
Pointer to classes
Struct에서 사용하는 방식과 동일하다고 생각하면 된다.
<Example 5>
// pointer to classes example #include using namespace std;
class Rectangle { int width, height; public: Rectangle(int x, int y) : width(x), height(y) {} int area(void) { return width * height; } };
int main() { Rectangle obj (3, 4); Rectangle * foo, * bar, * baz; foo = &obj; bar = new Rectangle (5, 6); baz = new Rectangle[2] { {2,5}, {3,6} }; cout << "obj's area: " << obj.area() << '\n'; cout << "*foo's area: " << foo->area() << '\n'; cout << "*bar's area: " << bar->area() << '\n'; cout << "baz[0]'s area:" << baz[0].area() << '\n'; cout << "baz[1]'s area:" << baz[1].area() << '\n'; delete bar; delete[] baz; return 0; } |
Expressions can be read as
*x |
pointed to by x |
&x |
address of x |
x.y |
member y of object x |
x->y |
member y of object pointed to by x |
(*x).y |
member y of object pointed to by x (equivalent to the previous one) |
x[0] |
first object pointed to by x |
x[1] |
second object pointed to by x |
x[n] |
(n+1)th object pointed to by x |
Overloading operators
class간에 operator에 대한 정의를 따로 지정해줄 수가 있다.
사실 지정 안해주면 compilation error가 난다.
<Example 6>
// overloading operators example #include using namespace std;
class CVector { public: int x,y; CVector () {}; CVector (int a,int b) : x(a), y(b) {} CVector operator + (const CVector&); };
CVector CVector::operator+ (const CVector& param) { CVector temp; temp.x = x + param.x; temp.y = y + param.y; return temp; }
int main () { CVector foo (3,1); CVector bar (1,2); CVector result; result = foo + bar; cout << result.x << ',' << result.y << '\n'; return 0; } |
여기서 const CVector& param에는 bar가 들어가게 된다.
쉽게 보려면 아래에 두 commands를 보면 되는데, 아래의 두 commands는 동일한 의미이다.
CVector a, b, c;
c = a + b; c = a.operator+ (b);
|
다음과 같이 non-member function으로도 쓸 수 있다.
(class 내부에 operator 선언이 안되어 있음)
이게 사실 더 명확한 것 같음.
<Example 7>
// non-member operator overloads #include using namespace std;
class CVector { public: int x,y; CVector () {} CVector (int a, int b) : x(a), y(b) {}
};
CVector operator+ (const CVector& lhs, const CVector& rhs) { CVector temp; temp.x = lhs.x + rhs.x; temp.y = lhs.y + rhs.y; return temp; }
int main () { CVector foo (3,1); CVector bar (1,2); CVector result; result = foo + bar; cout << result.x << ',' << result.y << '\n'; return 0; }
|
Static members