클래스의응용 클래스를자유자재로사용하자.
이장에서다룰내용 1 객체의치환 2 함수와클래스의상관관계
01_ 객체의치환 객체도변수와마찬가지로치환이가능하다. 기본예제 [7-1] 객체도일반변수와마찬가지로대입이가능하다. 기본예제 [7-2] 객체의치환시에는조심해야할점이있다. 복사생성자의필요성에대하여알아보자.
[ 기본예제 7-1] 클래스의치환 01 #include<iostream> 02 using namespace std; 03 class Unit { 04 int x,y; 05 public: 06 void set(int i, int j) { x=i; y=j; } 07 void show() { cout << x << ", " << y << "\n"; } 08 }; 09 10 int main(int argc, char* argv[]) 11 { 12 Unit A, B; 13 A.set(12,4); 14 B = A; 15 A.show(); 16 B.show(); 17 return 0; 18 } Unit 클래스를정의한다. A 를 B 에치환한다.
[ 기본예제 7-2] 클래스의치환 #2 01 #include<iostream> 02 #include<cstring> 03 using namespace std; 04 class Unit { 05 char* str; 06 public: 07 Unit() 08 { 09 str = NULL; 10 } 11 12 Unit(char* agstr) 13 { 14 int strlength = strlen(agstr); 15 str = new char[strlength + 1]; 16 strcpy(str, agstr); 17 } 18 19 void set(char* agstr) 20 { 21 strcpy(str, agstr); 22 } 23 24 void show() 25 { 26 cout << str << "\n"; 27 } 28 }; 29 30 int main(int argc, char* argv[]) 31 { 32 Unit A("TEST1"); 33 Unit B = A; 34 35 A.set("TEST2"); 36 37 A.show(); 38 B.show(); 39 return 0; 40 } Test1 의값을갖는 A 를생성한다. B 에 A 를복사한다. A 의내용을 내용을 Test1 Test1 에서 에서 B 로바꾼다.
01_ 객체의치환 복사생성자 기본예제 [7-2] 에서일어난이상한현상의이유를알려면, 복사생성자에대해서알아야한다. B 를생성하는데에는기본생성자가아닌복사생성자가사용된것이다. 기본생성자들이호출되는상황을파악하기위해서기본예제 [7-2] 를약간수정한기본예제 [7-3] 을실행해보자. 기본예제 [7-4] 에서복사생성자를추가하여실행해보자.
[ 기본예제 7-3] 클래스의치환 #3 07 Unit() 08 { 09 cout << "I'm a default constructor\n"; n"; 10 str = NULL; 11 } 12 13 Unit(char* agstr) 14 { 15 cout << "I'm a default constructor with parameters\n"; 16 int strlength = strlen(agstr); 17 str = new char[strlength + 1]; 18 strcpy(str, agstr); 19 } 32 int main(int argc, char* argv[]) 33 { 34 Unit A("TEST1"); 35 Unit B = A; 36 37 37 cout << " cout << "---------------------------------- " ----------------------------------\n"; 38 A.set("TEST2"); 39 40 A.show(); 41 B.show(); 42 43 return 0; 44 } 기본생성자가 생성자가실행된 실행된것을 것을화면에 화면에표시한다. 입력인자를실행된것을 인자를받은 받은경우에 것을화면에 경우에대한 화면에표시한다. 대한생성자가 Separator 표시.
[ 기본예제 7-4] 클래스의치환 #4 복사생성자추가 07 Unit() 08 { 09 cout << "I'm a default constructor\n"; 10 str = NULL; 11 } 12 13 Unit(char* agstr) 14 { 15 cout << "I'm a default constructor with parameters\n"; 16 int strlength = strlen(agstr); 17 str = new char[strlength + 1]; 18 strcpy(str, agstr); 19 } 20 Unit(Unit& agunit) 21 { 22 cout << "I'm a copy constructor\n"; n"; 23 str = agunit.str; 24 } 복사생성자가화면에표시한다. 생성자가실행된 실행된것을
01_ 객체의치환 얕은복사와깊은복사 얕은복사란, 우리가앞에서본예제들과같이 B 객체를생성하면서, 이미 A 가만들어놓은메모리의주소만을참조하도록복사하는것을의미한다. 깊은복사란, 얕은복사와는달리객체들간의간섭이일어나지않는아래와같은형태를의미한다.
[ 기본예제 7-5] 깊은복사 7-4 에서복사생성자만을수정. 07 Unit() 08 { 09 cout << "I'm a default constructor\n"; 10 str = NULL; 11 } 12 13 Unit(Unit& agunit) 14 { 15 cout << "I'm a copy constructor\n"; 16 str = new char[strlen(agunit.str) + 1]; 17 strcpy(str, agunit.str); 18 } 깊은복사를 복사를하기 하기위해서 문자열을복사한다. 위해서메모리를 메모리를새로 새로할당한다.
02_ 함수와클래스의상관관계 함수의입력인자로전달하는클래스객체 클래스객체를함수에전달하려면? 함수의 함수의입력인자로 입력인자로다른 다른기본 기본변수형들을 변수형들을전달하는 전달하는것과 것과동일하다. 즉, 함수의입력변수에대한정의를클래스형으로선언한다음, 함수를호출할때그클래스의객체를인자로사용하면된다.
[ 기본예제 7-7] 입력인자로전달하는클래스객체 01 #include <iostream> using namespace std; 02 class Unit { 03 int defaultarmor; 04 public: 05 Unit(int armor) { defaultarmor = armor; } 06 int GetDefaultArmor() { return defaultarmor; } 07 }; 08 클래스가입력인자인 입력인자인함수를 함수를정의한다. 09 int GetEnhancedArmor(Unit aunit) 10 { 11 return aunit.getdefaultarmor() * 2; 12 } 13 14 int main(int argc, char* argv[]) 15 { 16 Unit A(1), B(2); 17 cout << "Unit A : " << GetEnhancedArmor(A) << "\n"; 18 cout << "Unit B : " << GetEnhancedArmor(B) << "\n"; 19 return 0; 20 } A 와 B 클래스함수를수행한다. 클래스객체를 객체를입력인자로
02_ 함수와클래스의상관관계 함수로부터반환되는클래스객체 함수에게객체를입력인자로전달할수있는것과마찬가지로, 함수도클래스객체를반환할수있다. 객체를반환하기위해서는미리선언한후, 정상적인 return 문을사용하여반환하면 02_ 함수와된다클래스의. 상관관계
[ 기본예제 7-8] 반환되는클래스객체 01 #include <iostream> 02 using namespace std; 03 class Unit { 04 int defaultarmor; 05 public: 06 void Show() { cout << "defaultarmor : " << defaultarmor << "\n"; } 07 void Set(int armor) { defaultarmor = armor; } 08 }; 09 10 Unit GetUnit() 11 { 12 int armor; 13 Unit temp; 14 cout << "Enter a default armor : "; 15 cin >> armor; 16 temp.set(armor); 17 return temp; 18 } 19 20 int main(int argc, char* argv[]) 21 { 22 Unit a; 23 a = GetUnit(); 24 a.show(); 25 return 0; 26 } 클래스가객체를 객체를결과값으로 결과값으로반환한다. 함수의결과로받아서저장한다. 결과로클래스 클래스객체를
02_ 함수와클래스의상관관계 Friend 함수 클래스의멤버가아니면서도, 클래스의비공개원소에접근할수있게해주는함수이다. 하나의함수가두개이상의서로다른클래스들의비공개멤버에접근할수도 02_ 함수와있다. 클래스의상관관계 Friend 함수는멤버함수가아닌일반함수로정의되며, 함수명앞에 friend 라는키워드를붙여서선언한다.
[ 기본예제 7-9] friend 함수를이용한비공개멤버로의접근 01 #include <iostream> using namespace std; 02 class Unit { 03 int x,y; 04 public: 05 Unit(int i, int j) { x=i; y=j; } 06 friend bool issame(unit a); 07 }; 08 09 bool issame(unit a) 10 { 11 if (a.x == a.y ) return true; 12 else return false; 13 } 14 15 int main(int argc, char* argv[]) 16 { 17 Unit a(1,2), b(3,3); 18 19 cout << "a(1,2) : " << issame(a) << "\n"; 20 cout << "b(3,3) : " << issame(b) << "\n"; 21 return 0; 22 } Friend 함수를정의한다. Friend 함수의 함수의몸체를 몸체를구현한다. Friend 함수를호출한다.
예제모음 _12 의요구사항및실행결과 요구사항 1 다음과같은사각형클래스가있다. class Square{ public: int height,width; void addsquare(); }; 사각형클래스객체를입력으로받아서, 자신과입력받은사각형의넓이의합을화면에출력하도록함수 addsquare 를수정하라. 2 addsquare 를수정한후, 적당한생성자를만들어서 5x3, 4x4 인두객체에대해함수가정상적으로작동하는지화면에출력해본다. 실행결과
예제모음 _12 소스 01 #include <iostream> 02 using namespace std; 03 class Square { 04 public: 05 int height,width; 06 Square(int x, int y) 07 { 08 height = x; 09 width = y; 10 } 11 void addsquare(square A) 12 { 13 int area_a = A.height * A.width; 14 int area = height * width; 15 cout << " 두사각형넓이의합은 : " << area_a + area << "\n"; 16 } 17 }; 18 19 20 int main(int argc, char* argv[]) 21 { 22 Square A(5,3), B(4,4); 23 A.addSquare(B); 24 return 0; 25 } 생성자를구현한다. 클래스를입력인자로갖는멤버함수를정의하여넓이를계산한다.
예제모음 _13 의요구사항및실행결과 요구사항 1 다음과같은사각형클래스가있다. class Square{ int height,width; public: void addsquare(); }; 사각형클래스객체를입력으로받아서, 자신과입력받은사각형의넓이의합을화면에출력하도록함수 addsquare 를수정하라. 2 클래스의멤버변수인 height, width 는 private 로고정하고, 프렌드함수를 사용하도록한다. 3 addsquare 를수정한후, 적당한생성자를만들어서 5x3, 4x4 인두객체에대해함수가정상적으로작동하는지화면에출력해보도록한다. 실행결과
예제모음 _13 소스 01 #include <iostream> 02 using namespace std; 03 class Square { 04 int height,width; 05 public: 06 Square(int x, int y) 07 { 08 height = x; 09 width = y; 10 } 11 friend void addsquare(square A, Square B) 12 { 13 int area_a = A.height * A.width; 14 int area_b = B.height * B.width; 15 cout << " 두사각형넓이의합은 : " << area_a + area_b << "\n"; 16 } 17 }; 18 19 20 int main(int argc, char* argv[]) 21 { 22 Square A(5,3), B(4,4); 23 addsquare(a, B); 24 return 0; 25 } Friend 함수를입력받은넓이의합을 함수를정의하여 받은두객체의 합을구한다.
요약 클래스객체의치환 클래스객체도일반변수와동일하게치환이가능하다. 그러나클래스안에서포인터를다룰경우에는조심스럽게치환해야한다. 얕은복사와 깊은복사 메모리의주소만을참조하여주소만복사하는것을 얕은복사 (shallow copy) 라고하며, 원본값까지복사하는것을 깊은복사 (deep copy) 라고한다. 얕은복사로인해동작에문제가일어나는경우에는깊은복사를사용해야한다. [ 얕은복사의예 ] [ 깊은복사의예 ] 함수와클래스의상관관계 함수의입력인자로써다른기본변수형들을함수에전달하는것과같은방법으로클래스객체를함수에전달할수있으며, 함수의출력인자로써도동일한방법으로클래스객체를반환할수있다. Friend 함수 Friend 함수란클래스의멤버가아니면서해당클래스의비공개원소에접근할수있는함수를뜻한다. 주로이미작성된클래스의멤버들을크게수정하지않고접근해야할필요성이있을때사용된다.
www.themegallery.com IT CookBook for Beginner, C++ 기초 7 장끝