객체지향프로그래밍 (Object Oriented Programming) 12 장강사 강대기
차례 (Agenda) 멤버에대한동적메모리할당 암시적 / 명시적복사생성자 암시적 / 명시적오버로딩대입연산자 생성자에 new 사용하기 static 클래스멤버 객체에위치지정 new 사용하기 객체를지시하는포인터
StringBad 클래스 멤버에포인터사용 str static 멤버 num_strings 단하나만생성됨 static 클래스멤버초기화방법 (713 쪽 ) int StringBad::num_strings = 0; const 나 enum 을사용하여클래스선언안에서초기화 (619 쪽 ) 생성자에서 new[] 를사용하면파괴자에서 delete[] 를사용
StringBad 클래스사용 - vegnews.cpp (717 사용시의 (717 쪽 ) 시의문제점 callme2(headline2); 값으로함수인자전달 임시객체생성, 얕은복사수행 StringBad sailor = sports; 새로정의하는객체에대입 복사생성자를사용하거나, 복사생성자로임시객체생성후대입연산자사용 복사생성자, 대입연산자, 얕은복사수행 knot = headline1; 다른객체에대입 대입연산자사용, 얕은복사수행
컴파일러가몰래 몰래만드는 만드는멤버 멤버함수 생성자가없을경우, 디폴트생성자 복사생성자 대입연산자 파괴자 주소연산자 operator& 콤마연산자 operator,
디폴트생성자 어떠한생성자도만들지않으면생기며, 전달인자는없다 다른생성자를만들면, 없어짐 명시적으로디폴트생성자를만들거나 디폴트전달인자를사용하여구현 개선방안 this->str = new char[1]; 로초기화함
복사생성자 생성자 (723 (723 쪽 ) 어떤객체를받아서그내용을그대로복사해서, 새로운객체를생성 Class_name(const Class_name&); StringBad(const StringBad&); 호출되는예 StringBad ditto(motto); StringBad metoo = motto; StringBad also = StringBad(motto); StringBad* ps = new StringBad(motto); 또한객체를함수의전달인자로값으로전달할때 복사생성자도생성자이므로 new/ 초기화수행
대입연산자 (operator=) (728 쪽 ) 객체에다른객체를대입 Class_name& Class_name::operator=(const Class_name&); StringBad& StringBad::operator=(const StringBad&); 호출되는예 knot = headline1; StringBad metoo = knot; 문제해결방법 자기자신에게대입하는바보짓처리 왼쪽객체가가지고있는이전에할당된데이터를해제 오른쪽객체의값을깊게복사 호출한왼쪽객체에대한참조를리턴 보충 (738 쪽 ) StringBad& StringBad::operator=(const char *);
개선된 String 클래스 friend bool operator<(const String&, const String&); friend bool operator>(const String&, const String&); friend bool operator==(const String&, const String&); friend istream& operator>>(istream&, String&); char& operator[](int i); const char& operator[](int i); const
비교멤버 멤버 (734 (734 쪽 ) friend bool operator<(const String& s1, const String& s2) { } return (std::strcmp(s1.str,s2.str)<0); 프렌드함수로 String 객체와 C 스타일문자열비교 if ( love ==answer) if (operator==( love,answer)) // 프렌드함수 if (operator==(string( love ),answer)) // 생성자
[] 표기로 표기로개별 개별문자 문자접근 접근 (735 (735 쪽 ) String opera( The Magic Flute ); opera[4] opera[](int i) opera.operator[](4) means[0] = r ; // const 가아닌 operator means.operator[](0) = r ; means.str[0] = r ; const 객체를위해 const 멤버함수로오버로딩
static 클래스 클래스멤버 멤버함수 함수정의와함수선언이분리되어있으면, static 은함수선언에나타남 객체에의해호출되지않음 this 포인터도없음 클래스이름과사용범위연산자 (::) 로호출 int count = String::HowMany(); static 데이터멤버만사용가능, 아니면내부적으로객체생성
생성자에서 new new 를사용할 사용할경우 파괴자에서도 delete 를사용 new 는 delete 로, new[] 는 delete[] 로 포인터를 NULL 또는 0 으로초기화허용 깊은복사를하는복사생성자 EC++ #12 깊은복사를하는대입연산자 EC++ #11
객체리턴 객체, 객체참조, const 객체, const 객체참조 const 객체참조 효율성 ( 복사없음 ) 실행중에존재하는객체에대한참조 객체참조 효율성 ( 복사없음 ) 과필요성 연쇄적인대입이나출력 객체리턴 복사생성자가사용되며, 리턴되는객체가로컬일때유용 const 객체리턴 객체리턴이나참조리턴의오남용 (752 쪽 ) 을막음 net = force1+force2; // 오케이 force1+force2 = net; // 이상한프로그래밍 cout << (force1+force2 = net).magval() << endl; // 이상한프로그래밍
new 에의한 의한객체의 객체의초기화 초기화 (755 (755 쪽 ) Class_name: 클래스이름, value 가 Type_name 형 Class_name* pc = new Class_name(value); 다음생성자를호출 Class_name(Type_name); 다음생성자도가능 ( 사소한변환 ) Class_name(const Type_name &); 모호성이없는한일반적인변환은가능 예 : int 를 double 로 디폴트생성자호출 Class_name* pc = new Class_name
포인터와객체 파괴자 자동변수 블록을벗어나면호출 정적변수 프로그램이종료될때호출 동적변수 new 로생성 / delete 될때호출 new 로포인터초기화 String* f = new String(myString); 디폴트생성자 String* g = new String; String(const char *) 생성자 String* f = new String( my my my ); 멤버에접근하려면 ->, 객체에접근하려면 *
위치지정 지정 new new 다시 다시보기 메모리지정 new, Placement new placenew1.cpp (760 쪽 ) 동일한위치에위치지정 new 를두번한것 첫번째위치지정 new 의파괴자는호출되지않을것임 생성자나메소드가동적메모리할당을한다면더상황이나빠짐 위치지정 new 로생성된객체들은파괴자를호출하지않음 메모리가중복되지않게한다 p1 = new (buffer) JustTesting; p2 = new (buffer+sizeof(justtesting)) JustTesting; 파괴자를명시적으로호출한다 p1->~ JustTesting(); p3->~ JustTesting();
큐시뮬레이션 인터페이스 769 쪽코드 링크드리스트 770 쪽 큐클래스선언 (771 쪽 ) 내포된구조체정의로링크드리스트를넣음 (772 쪽노트 ) const 멤버변수초기화 (773 쪽 ) 멤버초기자리스트문법 774 쪽 ) enqueue(775 쪽 ), dequeue(777 쪽 ), 파괴자 (779 쪽 ) 새로운고객함수 newcustomer (785 쪽 )