한국방송통신대학교 출석수업담당김명진 ( 공학박사 ) 동양미래대학교겸임교수
1. 시작하기 C++ 프로그램의기본구조 동적메모리할당 함수
C++ 프로그램의소스파일 C++ 소스프로그램파일 처리하고자하는작업을수행하는 C++ 프로그램명령어들을담고있는파일파일의확장자 :.cpp,.cxx,.c 등 C++ 헤더파일 클래스, 함수의원형, 매크로, 전역변수, 상수등여러소스파일에공통적으로선언되는내용을담고있는파일단독으로컴파일되지않고, #include라는선행처리기지시어에의해소스프로그램에삽입되어함께컴파일된다. 확장자 : 일반적으로.h 를사용
C++ 프로그램의소스파일 예 : FirstStep.cpp 1 2 3 4 5 6 7 8 9 // 첫번째프로그램 #include <iostream> using namespace std; 주석선행처리기지시어 int main() cout << " 나의첫번째 C++ 프로그램 "; return 0;
C++ 프로그램의소스파일 선행처리란? C++ 소스프로그램을컴파일하기전에소스 프로그램을가공하여컴파일러가실제로번역할소스 프로그램을만드는것 선행처리기지시어 (preprocessor directives) 로처리를지시 선행처리기지시어문장은한행에한개의문장을작성 선행처리기지시어는 # 로시작함 대표적인선행처리 소스프로그램에헤더파일의내용삽입 조건부컴파일 매크로확장
C++ 프로그램의소스파일 선행처리의예 : 헤더파일삽입 a.cpp a.h #include "a.h" 문장 _1; 문장 _2; 문장 _3; 문장 _h1; 문장 _h2; 문장 _h3; 선행처리결과 문장 _h1; 문장 _h2; 문장 _h3; 문장 _1; 문장 _2; 문장 _3;
C++ 프로그램의소스파일 선행처리의예 : 헤더파일삽입 1 2 3 4 5 6 7 8 9 string cmath // 첫번째프로그램 iostream #include <iostream>... using namespace std;... int main() cout << " 나의첫번째 C++ 프로그램 "; return 0;
C++ 프로그램의소스파일 조건부컴파일 a.cpp int f(int x) #ifdef DEBUG_MODE cout << x << endl; #endif return x * x; DEBUG_MODE 정의됨 DEBUG_MODE 정의되지않음 선행처리결과 int f(int x) cout << x << endl; return x * x; int f(int x) return x * x;
C++ 프로그램의소스파일 예 : FirstStep.cpp 1 2 3 4 5 6 7 8 9 // 첫번째프로그램 #include <iostream> using namespace std; 주석선행처리기지시어명칭공간사용지정 int main() cout << " 나의첫번째 C++ 프로그램 "; return 0;
명칭공간 (namespace) 명칭공간이란? 특정한이름들이인식되는프로그램의부분 동일한명칭이라도서로다른명칭공간에서정의되었다면별개의것으로구분함 명칭공간 :: 명칭 여러프로그래머가작성한프로그램을결합하여완성된프로그램을만들경우각자필요한명칭을독립적으로만들어사용할수있음 전역명칭공간 : 특정명칭공간에속하지않는기본명칭공간 std 명칭공간 : 표준 C++ 라이브러리의명칭들이정의되어있는명칭공간 using namespace 구문 : 특정명칭공간을기본명칭공간에포함시키기위한구문
명칭공간 (namespace) 명칭공간적용예 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 #include <iostream> using namespace std; namespace mynsp1 int n = 10; namespace mynsp2 int n = 20; int n = 30; int main( ) int n = 40; std::cout << mynsp1::n << mynsp1::n << endl; << std::endl; std::cout << mynsp2::n << mynsp2::n << endl; << std::endl; std::cout << ::n << << ::n endl; << std::endl; std::cout << n << n endl; << std::endl; return 0;
C++ 프로그램의소스파일 예 : FirstStep.cpp 1 2 3 4 5 6 7 8 9 // 첫번째프로그램 #include <iostream> using namespace std; 주석선행처리기지시어명칭공간사용지정 int main() 실행할함수 cout << " 나의첫번째 C++ 프로그램 "; return 0;
기억공간의생명주기 전역변수함수외부에선언된 변수는프로그램전 영역에서사용할수있는 전역변수임 전역변수는프로그램 시작과함께생성되어 프로그램종료와함께 소멸됨 int a; void f ( ) int b; static int c; 전역변수
기억공간의생명주기 지역변수블록내에선언된변수는 그블록안에서만사용할 수있는지역변수임 자동변수 : 블록에들어갈 때생성되고나갈때 소멸됨 정적변수 : 프로그램 시작과함께생성되어 프로그램종료와함께 소멸됨 int a; void f ( ) int b; static int c; 전역변수 자동변수정적변수
기억공간의생명주기 동적메모리할당프로그램동작중에기억공간의필요성및소요량을 결정하여필요한공간을할당하는것 기억공간의생성시점 : new 연산자의실행시점 기억공간의소멸시점 : delete 연산자의실행시점 포인터변수가할당된기억공간을가리키게함
동적메모리할당및반납연산자 동적메모리할당연산자 1 2 ptrvar = new TypeName; ptrvar = new TypeName[n]; 동적메모리반납의연산자 1 2 delete ptrvar; delete [] ptrvar;
동적메모리할당 단일데이터공간의할당및반환 int *intptr; intptr = new int; int *intptr 자유메모리공간
동적메모리할당 단일데이터공간의할당및반환 int *intptr; intptr = new int; delete intptr; intptr = NULL; int *intptr NULL 자유메모리공간
동적메모리할당 연속데이터공간의할당및반환 int *intptr; intptr = new int[4]; int *intptr 자유메모리공간
동적메모리할당 연속데이터공간의할당및반환 int *intptr; intptr = new int[4]; delete [] intptr; intptr = NULL; int *intptr NULL 자유메모리공간
함수 C++ 프로그램을구성하는기본단위 필요한작업을수행하는프로그램문장들을하나의 단위로모아놓고이름을부여한것 프로그램의다른부분에서필요할때호출하여사용 매개변수를통하여함수에서처리할데이터를전달함 함수는정해진 처리를한후결과 값을반환할수 있음 실행을완료하면 호출한곳으로 복귀함 main( ) f( ); g( ); f( ); f( ) g( ) h( ); h( )
함수 함수사용의장점여러곳에서반복사용되는기능을함수로정의하면 동일코드를중복작성하지않아도됨 의미있는작업단위로모듈화하여프로그램을분할 작성함으로써, 간결하고이해하기쉬운프로그램을 만들수있음 함수사용의단점함수호출과복귀과정에서처리시간이추가됨 C++ 에서는 inline 함수제공
함수의정의및호출 함수정의형식 ReturnType functionname(fparameterlist) // 머리부 // 몸체블록 Type1 localvar1; // 지역변수정의 Type2 localvar2; statement1; // 처리할작업을수행하는문장 statement2; return returnexpression; // 결과값을반환 함수호출형식 functionname(fparameterlist); varname = functionname(fparameterlist);
함수사용예 - ConvFtoC.cpp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 19 20 21 22 23 #include <iostream> using namespace std; int main() float FahrToC(float fahr); // 함수원형 float ftemp, ctemp; // 지역변수선언 에러발생 cout << " 화씨온도 : "; cin >> ftemp; ctemp = FahrToC(fTemp); // 함수호출 cout << "---> 섭씨온도 : " << ctemp << endl; return 0; float FahrToC(float fahr) float c = (fahr-32) * 5 / 9; return c;
인수의전달 인수함수호출문장에서함수에전달하는값 매개변수를통해인수를전달함 실매개변수 (actual parameter) 함수호출문장에서 함수의형식매개변수에 전달할값 int main() ctemp = FahrToC(fTemp); 형식매개변수 (formal parameter) 인수를전달받기위해 함수에선언된매개변수 함수헤더에매개변수의 자료형과이름을선언 float FahrToC(float fahr) float c = (fahr-32)*5/9; return c;
인수전달방식 값호출 (call-by-value) 실매개변수의값을형식매개변수에복사 main() FahrToC(float fahr) ftemp 80 ctemp = FahrToC(fTemp); 값복사 fahr 80 main() ftemp 80 원본의값은불변 FahrToC(float fahr) fahr 80 48 사본의값을수정 fahr -= 32;
인수전달방식 참조호출 (call-by-reference) 참조변수 : 다른변수를참조하는변수 ( 포인터와유사함 ) 초기화를통해서만대상을참조할수있으며, 참조대상의별명처럼사용할수있음참조변수의선언형식 TypeName& refvar = varname; 참조변수사용예 int a = 10, b = 20; int &aref = a; aref = 100; aref = b; 100 20 20 a b a의참조 aref
인수전달방식 참조호출 (call-by-reference) 실매개변수의참조를형식매개변수에전달함수에서형식매개변수의값을변경하는것은실매개변수의값을변경하는것과같음형식매개변수에복사되는데이터의양은실매개변수의크기와관계없이일정함많은양의데이터로구성되는구조체나객체를인수로전달하는경우효율적임
인수전달방식 참조호출의예 - SwapInt.cpp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 #include <iostream> using namespace std; void SwapValues(int &x, int &y); // 원형 int main() int a, b; cout << " 두수를입력하시오 : "; cin >> a >> b; if (a < b) SwapValues(a, b); // 순서를바꿔 a에큰값을넣음 cout << " 큰수 = " << a << " 작은수 = " << b << endl; return 0;
인수전달방식 참조호출의예 - SwapInt.cpp 5 6 11 12 13 14 19 20 21 22 23 24 int main() if (a < b) SwapValues(a, b); // 순서를바꿔 a에큰값을넣음 cout << " 큰수 = " << a << " 작은수 = " << b << endl; return 0; void SwapValues(int &x, int &y) int temp = x; x = y; y = temp;
const 인수 실매개변수값의보호참조호출을하거나포인터를인수로전달할경우 함수에서실매개변수의값을수정할수있음 실매개변수의값을수정할수없도록하기위해서는 형식매개변수에 const 를지정함 함수호출의효율성을위해참조호출을하지만실 매개변수의값이변경되는것을원하지않을때
const 인수 4 5 6 7 8 20 21 22 23 24 25 26 27 예 - PrintRec.cpp struct SalesRec char pid[10]; int dyear, dmonth, ddate; 62바이트 char deliveraddr[40]; ; void PrSalesRec(const SalesRec &srec) // srec은상수인수 cout << " 품목코드 : " << srec.pid << endl; cout << " 배달일자 : " << srec.dyear << " 년 "; cout << srec.dmonth << " 월 "; cout << srec.ddate << " 일 " << endl; cout << " 배달주소 : " << srec.deliveraddr << endl;
디폴트인수 디폴트값을인수로전달하기위한방법대부분의경우일반적으로사용되는값이있는인수의 경우함수를정의할때그값을미리지정 함수를호출할때디폴트값을인수로사용할경우 생략할수있음 디폴트인수는인수리스트의끝에나열됨 예 istream& get(char* pch, int max, char delim='\n'); char str[10]; cin.get(str, 10); cin.get(str, 10, '\n') 과동일
함수의다중정의 다중정의 (overloading) 동일한이름에대하여여러가지의미를부여하는것 함수다중정의 동일한이름을갖는함수를여러개정의하는것동일한개념의처리를여러가지데이터나객체에대해각각의대상에맞는처리를해야할경우사용함수의구분 : 인수의개수및자료형
함수의다중정의 예 void f(int a) cout << a * a; void f(int a, int b) cout << a * b; int main( ) f(10); f(10, 20);
모호한함수다중정의주의 void g(int a) cout << a * a; void g(int a, int b=100) cout << a * b; int main( ) g(10, 20); g(10); // 선택기준이모호함
모호한함수다중정의주의 void h(int a) cout << a * a; void h(float a) cout << a * a; int main( ) h(10); h(10.0f); h(10.0); // 형변환대상이모호함
2. 클래스및객체개요 클래스와객체 클래스선언및객체정의 예제 : Box 클래스
추상화 추상화 (abstraction) 란? 세상에존재하는실제대상물의수많은특성 ( 속성, 행동등 ) 중에서응용분야에필요한요소들만으로구성된모델로표현하는것응용분야에따라필요한요소가다르므로동일한대상이라도추상화의형태는다름
추상화 예 : 자동차의추상화 엔진형식, 배기량, 최대출력, 최고속력, 변속기종류, 시트, 연료공급방식, 연료탱크용량, 연비, 완충장치, ABS, 에어백, 오디오, 선루프, 최대승차인원, 최대적재중량, 비디오게임 최대속력 가속성능 코너링성능 가속 / 감속 핸들조작
추상화 객체지향언어에서대상의모델링 데이터 -1 데이터 -2 데이터 -3 행위 -1 행위 -2 행위 -3 속성 (Attribute) 메소드 (Method)
캡슐화 캡슐화 (encapsulation) 란? TV 를시청하려면 TV 의동작원리를알아야한다? TV 를구동하는회로는내부에감춤 시청자는외부에마련된조작단추를 이용하여 TV 를시청함
캡슐화 캡슐화 (encapsulation) 란? TV 의내부설계가바뀌면사용방법도새로배워야한다? 화질및음질을개선하도록내부 설계를바꾸더라도외부조작단추가 동일하면사용방법은변하지않음
캡슐화 캡슐화 (encapsulation) 란? 객체내부의상세한구현 부분과외부사용자의 관점을분리함 내부속성등구현에대한 부분은공개하지 않으며 ( 정보은닉 ), 객체의 외부에서는공개된 인터페이스를통해객체를 사용할수있음 객체외부 직접사용불허 객체 내부구현 공개함수
캡슐화 캡슐화의장점 소프트웨어의유지보수가용이함 : 프로그램의다른부분에영향을미치지않고객체내부구현방법을수정할수있음재사용이용이함 : 잘설계된캡슐화된객체는다른응용에서도재사용할수있어소프트웨어개발비용을줄일수있음
클래스선언 클래스표현하고자하는대상의메소드와속성을선언한것 클래스 속성 메소드 객체의상태를표현데이터멤버객체의행위를정의멤버함수
클래스선언 클래스선언문의형식 class ClassName 가시성 _ 지시어 _1: 데이터멤버또는멤버함수리스트 ; 가시성 _ 지시어 _2: 데이터멤버또는멤버함수리스트 ; ;
클래스선언 가시성지시어클래스의멤버가공개되는범위를나타냄 종류 : private, public, protected 가시성지시어 private public 공개범위소속클래스의멤버함수친구클래스의멤버함수및친구함수전범위 디폴트는 private 임
객체의정의및사용 객체정의형식 ClassName objname; ClassName objname1, objname2, ; 객체사용형식멤버선택연산자 (.) 를사용하여멤버액세스 objname.datamember; objname.memfunc( );
( 예 ) Box 클래스 Box 클래스높이, 너비, 길이를갖는상자객체를만들기위한 클래스 Box 를정의한다. 멤버함수 void init(int h, int w, int d) : 높이, 너비, 길이를 각각 h, w, d 에전달된값으로초기화한다. int volume() : 상자의체적을계산하여반환한다. 데이터멤버 height, width, depth : 높이, 너비, 길이를나타내는 정수값을저장한다.
( 예 ) Box 클래스 class 클래스이름 Box private : 가시성 int height, width, depth; public : 가시성 ; 데이터멤버 void init(int h, int w, int d) height = h; width = w; 멤버함수 init() depth = d; int volume() const return height * width * depth; 멤버함수 volume()
( 예 ) Box 클래스 - Box 객체의사용 #include <iostream> using namespace std; class Box... ; int main() Box b; b.hight = 5; b.width = 10; 오류 b.depth = 10; cout << b.volume() << endl; return 0;
( 예 ) Box 클래스 - Box 객체의사용 #include <iostream> using namespace std; class Box... ; int main() Box b; b.init(5, 10, 10); cout << b.volume() << endl; return 0;
3. 클래스의설계 Counter 클래스의설계 소스파일의구성 실습 const 멤버함수
Counter 클래스의명세 Counter 클래스 계수기를나타내는클래스를선언하라. 계수기객체는값을 0으로지울수있고, 값을 1씩증가시킬수있으며, 현재의계수기값을알려줄수있다. reset count value 행위 속성 메소드 void reset() void count() int getvalue() 속성 int value 비고 계수기의값을 0으로지움계수기의값을 +1 증가시킴계수기의현재값을알려줌 비고 계수기의현재값을저장 Counter -value:int +reset():void +count():void +getvalue():int
소스파일의구성 ClassA.h class classa ; // 클래스멤버선언 ClassA.cpp #include "ClassA.h" // 클래스멤버정의 #include "ClassA.h" int main() ClassA 를사용하는파일들 #include "ClassA.h" void FuncA() #include "ClassA.h" void FuncB(ClassA &a)
Counter 클래스의선언 - Counter.h 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 #ifndef COUNTER_H_INCLUDED // Counter.h 가중복 include 되지않았는지검사 #define COUNTER_H_INCLUDED // Counter.h 가처음 include 될때정의됨 class Counter // 클래스 Counter의선언시작 int value; private 멤버선언 // : 데이터 private 멤버데이터멤버 value public: // public 멤버함수 void reset() // 계수기의값을 0으로지움 value = 0; Counter의멤버선언 void count() public 멤버 // 계수기의선언 : 값을 1 증가시킴 ++value; 멤버함수 reset(), count(), getvalue() int getvalue() const // 계수기의현재값을반환함 return value; ; #endif // COUNTER_H_INCLUDED
Counter 객체의정의및사용 - CntMain.cpp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 #include <iostream> #include "Counter.h" using namespace std; int main() 오류! private 멤버접근 Counter cnt; // Counter 객체의정의 cnt.value = 0; // 계수기를 0으로지움 cout << " 계수기의현재값 : " << cnt.value << endl; cnt.value++; // 계수기를 1 증가시킴 cnt.value++; cout << " 계수기의현재값 : " << cnt.value << endl; return 0;
Counter 객체의정의및사용 - CntMain.cpp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 #include <iostream> #include "Counter.h" using namespace std; cnt:counter -value?012 int main() Counter cnt; // Counter 객체의정의 cnt.reset(); // 계수기를 0으로지움 cout << " 계수기의현재값 : " << cnt.getvalue() << endl; cnt.count(); // 계수기를 1 증가시킴 cnt.count(); cout << " 계수기의현재값 : " << cnt.getvalue() << endl; return 0;
const 멤버함수 데이터멤버의값을수정하지않는멤버함수 Counter.h class Counter int value; public: void reset() value = 0; void count() ++value; int getvalue() const return value; ; const Counter c; int n = c.getvalue(); //? OK! c.count(); //? 오류
const 멤버함수 데이터멤버의값을수정하지않는멤버함수 Counter.h class Counter int value; public: void reset() value = 0; void count() ++value; int getvalue() const return value; ; void f(counter& c) int n = c.getvalue(); c.count(); // OK! void g(const Counter& c) int n = c.getvalue(); c.count(); // 오류
4. 생성자 생성자란? 생성자가포함된 Counter 클래스 초기화리스트
생성자 생성자 (constructor) 란? 객체가생성될때수행할작업을정의하는특수한 멤버함수 생성자의특성생성자의이름은클래스의이름과같다. 생성자는 return 명령으로값을반환할수없으며, 함수 머리에반환자료형을표시하지않는다. public 으로선언해야클래스외부에서객체를생성할 수있다. 생성자를다중정의할수있다.
생성자 생성자선언형식 class ClassName public: ClassName(fParameterList) ;
생성자의예 - Counter 클래스 Counter.h class Counter int value; public: void reset() value = 0; void count() ++value; int getvalue() const return value; ; CntMain.cpp cnt:counter int main() -value?0 Counter cnt; cnt.reset(); cout << " 계수기의현재값 : " << cnt.getvalue() << endl; cnt.count(); cnt.count(); cout << " 계수기의현재값 : " << cnt.getvalue() << endl; return 0;
생성자의예 - Counter 클래스 Counter.h class Counter int value; public: Counter() 생성자선언 value = 0; void reset() value = 0; void count() ++value; int getvalue() const return value; ; CntMain.cpp cnt:counter int main() -value 0 Counter cnt; cout << " 계수기의현재값 : " << cnt.getvalue() << endl; cnt.count(); cnt.count(); cout << " 계수기의현재값 : " << cnt.getvalue() << endl; return 0;
초기화리스트 초기화리스트란? 생성자의머리에데이터멤버를초기화하는값들을 나열한리스트 데이터멤버이름 ( 초깃값 ) 형태로초깃값을지정 Counter.h class Counter // 클래스 Counter의선언시작 int value; // private 데이터멤버 public: // public 멤버함수 Counter() : value(0) // 초기화리스트를사용하는생성자 ;
초기화리스트 초기화리스트를이용한상수데이터멤버의초기화 CounterM.h class CounterM // 클래스 CounterM의선언시작 const int maxvalue; // 계수기의최댓값 int value; // private 데이터멤버 public: // public 멤버함수 CounterM(int mval):maxvalue(mval+1), value(0) // 생성자 void reset() // 계수기의값을 0으로지움 value = 0; void count() // 계수기의값을 1 증가시킴 value = (value + 1) % maxvalue; int getvalue() const // 계수기의현재값을반환함 return value; ;
5. 소멸자 소멸자란? Person 클래스
소멸자 소멸자 (destructor) 란? 객체가소멸될때수행할작업을정의하는특수한멤버함수 소멸자의특성 1 소멸자의이름은클래스의이름과같으나, 앞에 ~ 가붙는다. 2 소멸자는 return 명령으로값을반환할수없으며, 함수머리에 반환자료형을표시하지않는다. 3 인수를전달받을매개변수를포함할수없다. 4 소멸자를다중정의할수없으며, 클래스에하나만정의한다. 5 public 으로선언하는것이일반적이다. 6 상속을통해파생클래스를정의하는경우 virtual 을지정하여 가상함수가되도록하는것이좋다.
소멸자 소멸자선언형식 class ClassName public: ClassName(fParameterList) // 생성자 // 객체생성을위한준비작업 ~ClassName() // 소멸자 ; // 객체제거를위한정리작업
Person 클래스의명세 Person 클래스 사람을나타내는클래스를선언하고자한다. 사람객체는 에사는 입니다. 라고자신을알릴수있으며, 주소를변경할수있다. 서울시종로구에사는이철수입니다. 행위 메소드 Person(char *name, char *addr) ~Person() void print() void chaddr(char *newaddr) 비고 생성자소멸자 에사는 입니다 라고출력함주소를변경함 속성 속성 char *name char *addr 이름을저장함 비 주소를저장함 고
Person 클래스의선언 - Person.h 1 2 3 4 5 6 7 8 9 10 11 12 #ifndef PERSON_H_INCLUDED #define PERSON_H_INCLUDED class Person // 클래스 Person의선언시작 char *name; // 이름을저장하는데이터멤버 char *addr; // 주소를저장하는데이터멤버 public: // public 멤버함수 Person(const char *name, const char *addr); // 생성자 ~Person(); // 소멸자 void print() const; // 이름과주소출력 void chaddr(const char *newaddr); // 주소변경 ; #endif // PERSON_H_INCLUDED
Person 클래스의선언 - Person.cpp 1 2 3 4 5 6 7 8 9 10 11 12 13 #include <iostream> #include <cstring> #include "Person.h" using namespace std; Person::Person(const char *name, const char *addr) this->name = new char[strlen(name)+1]; strcpy(this->name, name); this->addr = new char[strlen(addr)+1]; strcpy(this->addr, addr); cout << "Person 객체생성함 (" << name << ")" << endl;
Person 클래스의선언 - Person.cpp 15 16 17 18 19 20 21 22 23 24 25 Person::~Person() // 소멸자 cout << "Person 객체제거함 (" << name << ")" << endl; delete [] name; // 이름저장공간반납 delete [] addr; // 주소저장공간반납 void Person::print() const cout << addr << " 에사는 " << name << " 입니다." << endl;
Person 클래스의선언 - Person.cpp 22 23 24 25 26 27 28 29 30 31 32 void Person::print() const cout << addr << " 에사는 " << name << " 입니다." << endl; void Person::chAddr(const char *naddr) delete [] addr; // 기존공간반납 addr = new char[strlen(naddr)+1]; // 새로운주소에맞는공간할당 strcpy(addr, naddr); // addr에새로운주소를복사
Person 객체의생성및소멸 - PrsnMain.cpp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 #include <iostream> #include "Person.h" using namespace std; int main() 출력화면 Person 객체생성함 ( 이철수 ) Person 객체생성함 ( 박은미 ) 서울시종로구에사는이철수입니다. 강원도동해시에사는박은미입니다. 주소변경 : 대전시서구에사는박은미입니다. Person *p1 = new Person(" Person 이철수 ", 제거함 " 서울시 ( 이철수종로구 ) "); Person *p2 = new Person(" Person 박은미객체", 제거함 " 강원도 ( 박은미동해시 ) "); p1->print(); p2->print(); cout << endl << " 주소변경 : "; p2->chaddr(" 대전시서구 "); p2->print(); delete p1; delete p2; return 0;
6. 생성자의활용 디폴트생성자 복사생성자
디폴트생성자 디폴트생성자 (default constructor) 란? 매개변수가없는생성자, 또는모든매개변수에디폴트 인수가지정된생성자 클래스를선언할때생성자를선언하지않으면 컴파일러는아무런일도하지않는디폴트생성자를 만듦 생성자를하나라도선언하면컴파일러는디폴트 생성자를자동으로만들지않음
디폴트생성자 자동선언된디폴트생성자 Counter.h class Counter int Value; public: Counter() void reset() value = 0; void count() ++value; int getvalue() const return value; ; int main() Counter cnt;
디폴트생성자 디폴트생성자가없는클래스 CounterM.h class CounterM const int maxvalue; int Value; public: CounterM(int mval) : maxvalue(mval+1), value(0) void reset() value = 0; ; int main() CounterM cnt1(999); CounterM cnt2; // 에러
복사생성자 복사생성자 (copy constructor) 란? 같은클래스의객체를복사하여객체를만드는생성자 복사생성자를명시적으로선언하지않으면원본객체의 데이터멤버들을그대로복사하여객체를정의하는복사 생성자가자동적으로선언됨
복사생성자 자동선언된복사생성자 CounterM.h class CounterM const int maxvalue; int value; public: CounterM(int mval) : maxvalue(mval+1), value(0) CounterM(const CounterM &c) : maxvalue(c.maxvalue), value(c.value) void reset() value = 0; ; int main() CounterM cnt4(99); CounterM cnt5(cnt4); CounterM cnt6=cnt4;
복사생성자의활용예 - Copycat 클래스 Copycat 클래스 -name:char* Copycat +Copycat(n:const char*) +~Copycat() +whoru():void
복사생성자의활용예 - Copycat 클래스 8 9 10 11 12 13 14 15 16 17 18 19 20 21 class Copycat char *name; public: Copycat(const char *n) name = new char[strlen(n)+1]; strcpy(name, n); ~Copycat() delete [] name; void whoru() const cout << " 나는 " << name << " 입니다." << endl; ;
복사생성자의활용예 - Copycat 클래스 1 2 3 4 5 6 7 8 9 10 11 12 13 #include <iostream> #include "Copycat.h" using namespace std; int main() delete [] name; 홍길동 delete [] name; Copycat cc1(" 홍길동 "); Copycat cc2(cc1); // 복사생성자사용 cc1.whoru(); cc2.whoru(); return 0; cc1:copycat -name 출력화면 나는홍길동입니다. 나는홍길동입니다. < 에러발생 > cc2:copycat -name
복사생성자의활용예 - Copycat ( 수정본 ) 8 9 10 11 12 13 14 15 16 17 18 24 class Copycat char *name; public: Copycat(const char *n) name = new char[strlen(n)+1]; strcpy(name, n); Copycat(const Copycat &cc) name = new char[strlen(cc.name)+1]; strcpy(name, cc.name); ; Deep copy
복사생성자의활용예 - Copycat ( 수정본 ) 1 2 3 4 5 6 7 8 9 10 11 12 13 #include <iostream> #include "Copycat.h" using namespace std; delete [] name; int main() Copycat cc1(" 홍길동 "); Copycat cc2(cc1); cc1.whoru(); cc2.whoru(); return 0; cc1:copycat -name 홍길동 // 복사생성자사용 출력화면 나는홍길동입니다. 나는홍길동입니다. < 정상종료 > cc2:copycat -name 홍길동 delete [] name;
한국방송통신대학교 컴퓨터과학과이병래교수