일반적으로클래스는 생성자(constructor)와 소멸자(destructor)라 불리는 메소드를 정의할 수 있게 되어 있다. 


생성자는 인스턴스 객체가 생성될 때 초기화를 위해서 자동적으로 불려지는 초기화 함수를 말하고,

소멸자는 인스턴스 객체가 사용이 끝나서 메모리에서 해제될 때 자원 해제를 위해서 자동으로 호출되는 함수를 말한다.


파이썬 클래스에서는 생성자와 소멸자를 위해 특별한 이름을 준비해 놓고 있다.

생성자 함수 이름은 __init__ 

소멸자 함수 이름은 __del__


※     일반적으로 파이썬에서는 어떤 이름 앞뒤로 _(언더라인)이 두 개씩 붙어 있으면, 예약어(Reserved Words) 이다.

클래스 메소드로써는 미리 어떤 기능이 정의된 경우를 의미한다.



생성자는 대부분 인스턴스 멤버를 생성하고 값을 초기화하는 데 주로 사용된다.

소멸자는 실제로 많이 활용되지는 않는다. 왜냐하면, 대부분의 메모리나 기타 자원 관리가 자동으로 되기 때문에 특별히 신경 쓰지 않아도 인스턴스가 소멸하면서 자원이 원상 복귀되기 때문이다.


'Programming > Python' 카테고리의 다른 글

협동적 메소드와 super()  (0) 2013.05.07
연산자 오버로딩  (0) 2013.05.02
class member, instance member  (0) 2013.05.02
정적 메소드, 클래스 메소드, 장식자  (0) 2013.05.01
메쏘드의 정의와 호출  (0) 2013.05.01
Posted by scii
:

복사 생성자


C++에서는 다음의 방식으로 선언 및 초기화가 가능하다.

int num(20);






Simple형 객체를 생성해라.

객체의 이름은 sim2로 정한다.

sim1을 인자로 받을 수 있는 생성자의 호출을 통해서 객체생성을 완료한다.


위의 객체생성문에서 호출하고자 하는 생성자는 다음과 같이 Simple 객체를 인자로 받을 수 있는 생성자이다.


Simple(Simple &copy)

{

}


그리고 다음의 문장도, 

Simple sim2 = sim1;


실은 다음의 형태로 묵시적 변환이 되어서(자동으로 변환이 되어서) 객체가 생성되는 것이다.

Simple sim2(sim1);



----------------------------------------------------------------------------------------------------------------------------------------




32행의 문장이 묵시적으로(자동으로) 변환된다는 사실만 제외하면 특별할 게 없는 예제이다. 14행에 정의된 생성자도 이해할만한 수준의 생성자이다. 그런데 이러한 생성자를 가리켜 별도로 "복사 생성자(Copy Constructor)" 라 부른다.

이는 생성자의 정의형태가 독특해서 붙은 이름이 아니다. 다만 이 생성자가 호출되는 시점이 다른 일반 생성자와 차이가 있기 때문에 붙은 것이다.

즉, 복사 생성자를 정확히 이해하기 위해서는 복사 생성자의 호출시점을 확실히 이해해야 한다.


----------------------------------------------------------------------------------------------------------------------------------------


자동으로 삽입이 되는 디폴트 복사 생성자


: 복사 생성자를 정의하지 않으면, 멤버 대 멤버의 복사를 진행하는 디폴트 복사 생성자가 자동으로 삽입된다.


생성자가 존재하더라도, 복사 생성자가 정의되어 있지 않으면 디폴트 복사 생성자라는 것이 삽이되어 멤버 대 멤버의 복사를 진행한다.


class Simple

{

int num1;

int num2;


public:

Simple(int n1, int n2) : num1(n1), num2(n2)

{ }

};


class Simple

{

int num1;

int num2;


public:

Simple(int n1, int n2) : num1(n1), num2(n2)

{ }

Simple(const Simple &copy)  : num1(copy.num1), num2(copy.num2)

{ }

};


위의 두 클래스 정의는 완전히 동일한 것이다. 디폴트 복사 생성자가 자동으로 삽입되기 때문이다.


※ 많은 경우에 있어서 복사 생성자를 직접 정의하지 않아도 된다. 그러나 반드시 복사 생성자를 정의해야 하는 경우도 있다.

'Programming > C++' 카테고리의 다른 글

깊은 복사 & 얕은 복사  (0) 2012.05.24
explicit  (0) 2012.05.23
this 포인터  (0) 2012.05.21
객체 배열 & 객체 포인터 배열  (0) 2012.05.21
생성자 & 소멸자를 이용한 예제  (0) 2012.05.21
Posted by scii
:

#include <iostream>

#include <cstring>

using namespace std;


namespace COMP_POS

{

enum {CLERK, SENIOR, ASSIST, MANAGER};


void Select(int pos)

{

switch(pos)

{

case CLERK:

cout<<"사원"<<endl; break;

case SENIOR:

cout<<"주임"<<endl; break;

case ASSIST:

cout<<"대리"<<endl; break;

case MANAGER:

cout<<"과장"<<endl; break;

}

}

}


class NameCard

{

private:

char * name;

char * companyName;

char * tel;

int position;


public:

NameCard(char* na, char* comp, char* tele, int pos)        //생성자

:position(pos)                                

{

int len1 = strlen(na)+1;

int len2 = strlen(comp)+1;

int len3 = strlen(tele)+1;

name = new char[len1];

strcpy(name, na);

companyName = new char[len2];

strcpy(companyName, comp);


tel = new char[len3];

strcpy(tel, tele);

}

void ShowNameCardInfo(void) const

{

cout<<"이름 :"<<name<<endl;

cout<<"회사 :"<<companyName<<endl;

cout<<"전화번호 :"<<tel<<endl;

cout<<"직급 :"; COMP_POS::Select(position);

cout<<endl;

}

~NameCard()                                                            //소멸자

{

delete []name;

delete []companyName;

delete []tel;

}

};


int main(void)

{

NameCard manClerk("Lee", "abc", "010-875-5543", COMP_POS::CLERK);

NameCard manSenior("Jane", "def", "010-232-3439", COMP_POS::SENIOR);

NameCard manAssist("Jeon", "ghi", "010-844-1245", COMP_POS::ASSIST);


manClerk.ShowNameCardInfo();

manSenior.ShowNameCardInfo();

manAssist.ShowNameCardInfo();


return 0;

}


실행결과



'Programming > C++' 카테고리의 다른 글

this 포인터  (0) 2012.05.21
객체 배열 & 객체 포인터 배열  (0) 2012.05.21
생성자를 이용한 예제.  (0) 2012.05.21
소멸자(Destructor)  (0) 2012.05.20
private 생성자  (0) 2012.05.20
Posted by scii
:

Point 클래스는 점의 좌표를 알려주는 클래스이고, Circle 클래스는 원의 반지름과 중심점의 좌표를 알려주는 클래스이다. 그리고 마지막으로 Ring클래스는 Point, Circle 클래스를 묶는(캡슐화) 클래스이다. Ring클래스는 좌표정보와 반지름을 입력받아 Point, Circle에 전달한다. 


#include <iostream>

using namespace std;


class Point

{

private:

int xpos, ypos;


public:

Point(int x, int y) : xpos(x), ypos(y)         //Constructor

{}

void ShowPointInfo(void) const

{

cout<<"["<<xpos<<", "<<ypos<<"]"<<endl;

}

};


class Circle

{

private:

Point coord;

const int rad;


public:

Circle(const int x, const int y, const int r)

:coord(x, y), rad(r) //Constructor

{}

void ShowCircleInfo(void) const

{

cout<<"radius: "<<rad<<endl;

coord.ShowPointInfo();

}

};


class Ring

{

private:

Circle c1;

Circle c2;


public:

Ring(int x1, int y1, int r1, int x2, int y2, int r2)

:c1(x1, y1, r1), c2(x2, y2, r2)         //Constructor

{}

void ShowRingInfo(void) const

{

cout<<"Inner Circle Info..."<<endl;

c1.ShowCircleInfo();

cout<<"Outter Circle Info..."<<endl;

c2.ShowCircleInfo();

}

};


int main(void)

{

Ring ring(1, 1, 4, 2, 2, 9);

ring.ShowRingInfo();


return 0;

}


실행결과



'Programming > C++' 카테고리의 다른 글

객체 배열 & 객체 포인터 배열  (0) 2012.05.21
생성자 & 소멸자를 이용한 예제  (0) 2012.05.21
소멸자(Destructor)  (0) 2012.05.20
private 생성자  (0) 2012.05.20
디폴트 생성자(Default Constructor)  (0) 2012.05.20
Posted by scii
:

메모리 공간의 할당 이후에 생성자의 호출까지 완료되어야 '객체'라 할 수 있다. 

즉, 객체가 되기 위해서는 반드시 하나의 생성자가 호출되어야 한다. 그리고 이러한 기중에 예외를 두지 않기 위해서 생성자를 정의하지 않는 클래스에는 C++ 컴파일러에 의해서 디폴트 생성자라는 것이 자동으로 삽입된다.


- 디폴트 생성자는 인자를 받지 않으며, 내부적으로 아무런 일도 하지 않는 생성자이다. -


class A

{

int num;


public:

int GetNum(void)

{

return num;

}

};


class A

{

int num;


public:

A() {} //디폴트 생성자.

int GetNum(void)

{

return num;

}

}; 


위의 2개의 클래스는 완전히 동일하다.


따라서, 모든 객체는 한번의 생성자 호출을 동반한다. 이는 new 연산자를 이용한 객체의 생성에도 해당하는 이야기다. 

즉, 위의 클래스를 다음의 형태로 생성해도 객체의 생성과정에서 생성자가 호출된다.

A * ptr = new A;


단, 다음과 같이 new연산자가 아닌, C언어의 malloc 함수를 대신 이용하면 생성자는 호출되지 않는다.

A * ptr = (A*)malloc(sizeof(A));


malloc 함수호출 시, 실제로는 A클래스의 크기정보만 바이트 단위로 전달되기 때문에 생성자가 호출이 되지 않는다.


$ 객체를 동적으로 할당하려는 경우에는 반드시 new 연산자를 이용해야 한다.



생성자 불일치


위에 보인, 매개변수가 void형으로 선언되는 디폴트 생성자는 생성자가 하나도 정의되어 있지 않을 때에만 삽입이 된다. 즉, 다음과 같이 정의된 클래스에는 디폴트 생성자가 삽입되지 않는다.


class A

{

int num;


public:

A(int n) : num(n) {} //int형 하나를 인자로 받는 생성자.

};


따라서 다음의 형태로는 객체성성이 가능하다.

A simple(10);

A * simPtr = new A(10);


그러나 다음의 형태로는 개체생성이 불가능하다. 다음 문장에서 요구하는 생성자가 정의되지도, 자동으로 삽입되지도 않았기 때문이다.

A simple;

A * simPtr = new A();


따라서 위의 형태로 객체를 생성하기 원한다면, 다음의 형태로 생성자를 추가해야 한다.

A() : num(0) {}

'Programming > C++' 카테고리의 다른 글

소멸자(Destructor)  (0) 2012.05.20
private 생성자  (0) 2012.05.20
이니셜라이저(Initializer)  (0) 2012.05.19
생성자(Constructor)  (0) 2012.05.12
캡슐화  (0) 2012.05.12
Posted by scii
:

생 성 자


클래스 정의에서 다음의 형태를 띠는 함수가 생성자이다.


# 클래스의 이름과 함수의 이름이 동일하다.

# 반환형이 선언되어 있지 않으며, 실제로 반환하지 않는다.


이러한 유형의 함수를 가리켜 '생성자'라 하며, 생성자는 "객체 생성시 딱 한번 호출된다."

----------------------------------------------------------------------------------------------------------------------------------------------------------------


* 생성자도 함수의 일종이니 오버로딩이 가능하다.

* 생성자도 함수의 일종이니 매개변수에 '디폴트 값'을 설정할 수 있다.





28라인의 함수 void SimpleClass(void) 와 46라인의 함수void SimpleClass(int n1=1, int n2=0) 를 다음과 같은 문장으로 구성하면 안된다.

SimpleClass sc1();                (X)



다음과 같이 구성을 해야 한다.

SimpleClass sc1;                                                    (O)

SimpleClass * ptr = new SimpleClass;                  (O)

SimpleClass * ptr = new SimpleClass();                (O)


매개변수가 선언되어 있지 않으니 소괄호를 생략할 수 있다.



그렇다면, 다음 문장도 허용이 가능할 것 같은데 허용이 안된다!!

SimpleClass sc1();                (X)



예제)



출력 결과 : 20, 30


※ 보통 함수의 원형은 전역적으로(함수 밖에) 선언하지만, 위 예제에서 보이듯이 함수내에 지역적으로도 선언 가능하다.


위 예제의 42라인의 문장은 이러한 함수의 원형 선언에 해당된다. 즉, 이 문장을 void형(인자를 받지 않는) 생성자의 호출문으로 인정해 버리면, 컴파일러는 이러한 문장을 만났을 때, 이것이 객체생성문인지 함수의 원형선언인지를 구분할 수 없게 된다.


그래서 이러한 유형의 문장은 객체생성이 아닌, 함수의 원형선언에만 사용하기로 약속하였다.


'Programming > C++' 카테고리의 다른 글

디폴트 생성자(Default Constructor)  (0) 2012.05.20
이니셜라이저(Initializer)  (0) 2012.05.19
캡슐화  (0) 2012.05.12
const 함수  (2) 2012.05.08
정보은닉(Information Hiding)  (0) 2012.05.03
Posted by scii
: