1 / 27

Reference/Copy Constructor

Reference/Copy Constructor. C++ Programming 강 성 관. 지역 변수와 전역변수 (local varible & global varible). 지역 변수 어떤 함수내부에서 선언된 변수 소속된 함수 내부에서만 사용 가능 선언할 때 초기값을 주는 것이 가장 이상적 초기값을 안 줄 경우 정수형이나 문자형 변수 모두 쓰레기 값으로 자동으로 초기화 됨 전역 변수 어느 함수에도 속하지 않은 변수 선언할 때 초기값을 줄 수 있음 선언할 때 초기값을 안 줄 경우

thao
Download Presentation

Reference/Copy Constructor

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Reference/Copy Constructor C++ Programming 강 성 관

  2. 지역 변수와 전역변수 (local varible & global varible) • 지역 변수 • 어떤 함수내부에서 선언된 변수 • 소속된 함수 내부에서만 사용 가능 • 선언할 때 초기값을 주는 것이 가장 이상적 • 초기값을 안 줄 경우 • 정수형이나 문자형 변수 모두 쓰레기 값으로 자동으로 초기화 됨 • 전역 변수 • 어느 함수에도 속하지 않은 변수 • 선언할 때 초기값을 줄 수 있음 • 선언할 때 초기값을 안 줄 경우 • 정수형 변수는 자동으로 0으로 초기화 됨 • 문자형 변수는 자동으로 ‘\0’(null 문자) 값으로 초기화 됨. • 프로그램 내에 있는 모든 함수가 사용할 수 있음 • 변경된 값이 어느 함수에서 출력해봐도 일정한 값이 출력됨.

  3. 정적 기억 공간 & 정적 변수 • 프로그램이 실행되는 동안에 지속적으로 존재하는 공간. • 정적 변수 • 프로그램이 실행되는 전체 시간 동안 계속 존속한다. • 스택(stack)에 저장되지 않는다. • 넉넉하게 크기가 정해진 메모리 블록은 프로그램이 실행되는 동안에 크기가 변하지 않는다. • 명시적으로 초기화하지 않으면 모두 0으로 설정된다. • 명시적으로 초기화 했을 경우 실행할 때 오직 한번만 초기화 된다. (1)전역 변수 함수의 외부에서 정의 (2) static 키워드를 붙여서 함수 내에서 정의. (3) static 키워드를 붙여서 함수 외부에서 정의. static int fee = 56 ; Ex) static double fee = 56.50 ;

  4. Memory 데이터 생성 구조도

  5. Stack(스택)의 정의 (1) ① 프로그램에서 각 함수에 의해 필요로 되는 자료들을 보관하기 위해 할당된 메모리의 특수한 영역 ② 입▪출력(Insertion/Deletion)이 리스트의 한쪽 끝으로만 제한된 리스트 last-in-first-out [LIFO] 구조 입력                               출력 (insertion)                 (deletion) <스택의 동작 구조> ③ limit : 입▪출력이 허용되는 리스트의 끝 BOTTOM : TOP의 반대쪽 끝 ④ Stack pointer : 가장 최근에 입력된 value의 위치를 가리키는 포인터 (출력 우선 순위가 가장 높은 value를 가리키는 포인터) ⑤ 컴파일러, 서브루틴의 복귀주소(return address)기억에 사용

  6. Stack (2) index stack stack stack stack 6 5 4 F 3 E D 2 C B 0 2 3 4 C TOP 1 A A TOP A TOP ⒜ ⒟ ⒝ ⒞

  7. Stack (3) ⑴ 입력과 출력의 개념 ⓐ 초기상태 TOP = nil ⓑ A를 입력하고 (TOP=1) 계속해서 B를 입력한 상태 ⓒ B를 출력하고 (TOP=1) C를 입력(TOP=2) 한 다음 이어서 D를 입력한 상태 ⓓ D를 출력하고 (TOP=2) E를 입력(TOP=3) 한 다음 이어서 F를 입력한 상태 ⑵ 스택에서 입력과 출력의 알고리즘 ① 입력(insert, push, put) : 최대 인덱스값(stack length)을 N이라 하면 ㉮ IF TOP = nil이면 TOP=0; ㉯ TOP ← TOP+1; ㉰ TOP>N 이면 overflow 이므로 exit; TOP≤N 이면 STACK[TOP] ← new atom; ② 출력(delete, pop, pull) ㉮ IF TOP = nil이면 underflow 이므로 exit; ㉯ remove STACK[TOP]; ㉰ TOP ← TOP -1; ㉱ IF TOP = 0이면 TOP ← nil;

  8. 참조자(reference) • 변수의 또 다른 이름으로 사용되는 내재된 포인터 • 일종의 또 다른 이름 “ 별칭(alias)” • 참조자를 만들때 다른 변수의 이름(타겟) 으로 초기화 하고 이 때부터 참조자는 이 타겟에 대한 다른 이름으로 행세. • 참조자(reference)의 사용 -함수에게 전달될 때(call by reference) • w인수의 주소를 전달해야 한다는 사실을 더 이상 기억할 필요가 • 없다. w코드의 판독성 및 유지 보수성을 향상시킬 수 있다. w객체가 참조로 함수에게 전달될 때 복사본이 만들어지지 않는다(객체의 주소만을 넘겨 준다). -함수로부터 반환될 때 • 참조자(reference)의 선언- 타겟 변수의 형을 쓰고 참조 연산자(&) 다음에 참조자의 이름을 쓴다. 예 ) int someInt ; int &rSomeRef = someInt ; => ‘rSomeRef는 someInt를 참조하도록 초기화된 정수형 참조자’

  9. 포인터와 참조자(reference) • 공통점 • 둘 다 메모리 주소를 다룬다. • 차이점 • 사용하는 방식이 다르다. • 포인터 : 별도의 메모리 공간을 차지 • 참조자 : 별도의 메모리 공간을두는 것이 아니라 같은 공간을 공유 • 포인터에서의 &(주소 연산자) • 메모리 주소를 얻어오는 경우pvalue = &nValue ; Test(&nValue) ; • 참조 연산자(&) • 변수를 선언할 때, 함수에 인자를 넘겨줄 때 int &Reference ; void Test(int &Reference) ;

  10. 참조형 인자를 사용한 함수 호출 • 함수 인자에서 참조 연산자를 선언 • 함수를 부르는 쪽에서는 일반 인자를 넘기는 것과 같다. • 함수를 부를 때 인자가 포인터형 일 때는 변수 주소나 포인터가 오고, 참조형 일 때는 반드시 변수가 온다 • 참조형을 이용하는 경우 void increase(int &nVal) { nVal++ ; } void main() { int nValue ; increase(nValue) ; }

  11. 참조자(3) • 포인터와 참조자 #include<iostream.h> void f(int &n); main() { int i = 0; f(i); cout << “Here is i’s new value:” << i << “\n”; return 0; } void f(int &n) //n의 메모리 생성 안됨 { n = 100; } #include<iostream.h> void f(int *n); main() { int i = 0; f(&i); cout << “Here is i’s new value:” << i << “\n”; return 0; } void f(int *n) //n의 메모리 생성 { *n = 100; }

  12. 객체에 대한 참조의 전달(1) • 참조로 객체를 전달 -생성자 함수 및 소멸자 함수 호출 안 함 • Call-by-Value 방식 -생성자 함수 호출 함 -소멸자 함수 호출 함 • 예제 프로그램 #include<iostream.h> class myclass { int who; public : myclass(int n) { who = n; cout << “Constructing” << who << “\n”; } ~myclass() { cout << “Destructing…\n”; } int id() { return who; } };

  13. void f(myclass &o) // 생성자 함수 호출 안 함, Why? { cout << “Received” << o.id() << “\n”; } // 소멸자 함수 호출 안 함. main() { myclass x(1); // 생성자 함수 호출 f(x); return 0; } // 소멸자 함수 호출  Result :

  14. 참조의 반환 • 연산자 중복을 정의할 때 유용 • 예제 프로그램 #include<iostream.h> int &f(); int x; main() { f() = 100;// x = 100; 과 동일 cout << x << “\n”; return 0; } int &f() { return x;// x에 대한 참조를 반환한다. } Result :

  15. 객체의 치환(1) • 하나의 객체는 같은 형의 다른 객체로 치환 - 모든 데이터 멤버들은 비트 단위로 복사 #include<iostream.h> class myclass { int a, b; public: void set(int i, int j) { a = i; b = j; } void show() { cout << a << ‘ ’ << b << “\n”; } };

  16. 객체의 치환(2) main() { myclass o1, o2; o1.set(10,4); o2 = o1;// o1을 o2에 치환 o1.show(); o2.show(); return 0; } - 같은 형의 객체만 사용 -복사가 이루어질 때에는 객체 안의 모든 데이터 멤버가 다른 객체로 치환된다. w멤버가 문자열 일지라도 복사가 이루어진다. w포인터 변수에 대해서는 복사 시 run-time 에러 발생 - 해결 : 복사 생성자 사용

  17. 예제 : 메모리할당을 통한 문자열 저장(1) strtype :: strtype(char *ptr) { len = strlen(ptr); p = new char[ len+1 ] ; if(!p) { cout << “Allocation error\n”; exit(1); } strcpy(p, ptr); } #include<iostream.h> #include<iostream.h> #include<string.h> #include<stdlib.h> class strtype { char *p; int len; public: strtype(char *ptr); ~strtype(); void show(); };  뒤에 계속

  18. 예제 : 메모리할당을 통한 문자열 저장(2) strtype :: ~strtype() { cout << “Freeing p\n”; delete p ; } void strtype :: show() { cout <<p << “-length :” <<len; cout << “\n”; }  뒤에 계속

  19. 예제 : 메모리할당을 통한 문자열 저장(3) main() { strtype s1(“This is a test”), s2(“I like C++”); s1.show(); s2.show(); s2 = s1; // 객체 치환에 의한 run-time에러 발생 // 해결 : 복사 생성자 사용 s1.show(); s2.show(); return 0; }

  20. 할당 연산자(=)와 복사생성자(copy constructor)(1) • ‘=‘연산자를 이용해서 할당 연산자나 복사 생성자를 호출한다. • 형식 • Person temp , p ; • temp = p ; //할당연산자 호출 • temp.show() ; • (2) Person p; • Person temp = p ; //복사생성자 호출 • tmp.show() ; • 할당 연산자 함수는 객체 값을 할당한 다음 객체 자신(*this)을 리턴하는데 이 값은 다음 할당 연산자 함수에 인자로 넘겨집니다. • 리턴된 객체는 다시 다음 할당 연산자 함수에 인자로 넘겨진다. 예) Person temp1, temp2 , anony(“하마입”) ; temp2 = temp1 = anony ;

  21. 할당 연산자(=)와 복사생성자(copy constructor)(2) (1)할당 연산자 함수 class Person { char *mouth ; int height ; public : Person const &operator=(Person const &other) ; ~Person() { delete[] mouth ; } }; 선언 부분 Person const &Person::operator=(Person const &other) { mouth = other.mouth ; height = other.height ; } 정의 부분

  22. 할당 연산자(=)와 복사생성자(copy constructor)(3) • 할당 연산자 함수의문제점 • 어떤 클래스의 멤버 변수가 포인터 변수가 없을 때는 문제가없으나 포인터 변수가 있을 때는 복사시 포인터 변수끼리 주소값이복사되어 같은 공간을 공유하게 된다. • 소멸자가 동작할 때 첫번째 객체가 지운 500번지 공간을 다음 객체의 소멸자가 또 지우려 할 때 문제가 발생. other.mouth 500번지 mouth 500번지 500번지

  23. 할당 연산자(=)와 복사생성자(copy constructor)(4) (2) 복사 생성자 함수 Person(Person const &other) ; 선언 부분 Person::Person(Person const &other) //복사 생성자 정의 부분 { pName = AllocString(other.pName) ; nAge = other.nAge ; } 정의 부분 • 복사 생성자 함수 • 자신과 같은 형(type = class)의 객체를 참조에 의해 인자로 받아들이는 생성자

  24. 복사 생성자(Copy Constructor) • 객체의 복사본이 만들어 질 때마다 항상 호출되며 어떤 것이 일어 나야 할지를 정확하게 지정할 수 있다. • -형식 • classname (const classname &ob) { // body of constructor } • 예) CAT ( const CAT &theCat ) ; • 모든 복사 생성자는 하나의 매개변수를 가지는데 같은 클래스 타입의 객체에 대한 참조자 이다. • 이 매개변수를 상수 참조자로 만들어 놓는다. • 왜? => 생성자가 전달된 객체를 바꾸지 못하도록 • 예) CAT ( const CAT &theCat ) ; • CAT 생성자는 이미 존재하는 CAT 객체에 대해 상수 참조자를 가진다. • 복사 생성자의 목적은 theCat에 대한 복사본을 만드는 것. • 기본 복사 생성자는 매개변수로 전달된 객체의 각 멤버 변수들 중에서 포인터 변수가 가리키는 공간은 새로운 객체와 공유(aliasing)한다. (shallow copy).

  25. 복사 생성자(Copy Constructor)(2) • itsAge 는 CAT 클래스 안에 있는 멤버변수로서 포인터 변수 • old CAT과 New CAT은 각각 CAT 클래스의 첫번째와 두번째 객체 자유기억공간 • 기본 복사 생성자(얕은복사) • 두 개의 객체는 같은 메모리를 포인트 old CAT New CAT itsAge itsAge 자유기억공간 • 깊은 복사의 예 • 사용자가 정의한 복사생성자 • 두 개의 객체는 다른 메모리를 포인트 old CAT New CAT itsAge itsAge

  26. 함수로부터 객체의 반환(1) • 함수의 결과로서 객체를 반환할 수 있다. - 반환형으로 클래스형을 함수와 같이 선언 - return문을 사용 • 함수로부터 객체를 반환할 때 중요한 점 - 할당 연산에서함수에서 반환될 때 반환값을 저장하기 위한 임 시 객체(temporary object)가 자동으로 생성 • - 값이 반환된 후 임시객체는 소멸

  27. 복사 생성자의 사용 • 복사 생성자의 사용 이유 -객체가 함수의 인자로서 사용된 경우 w포인터 변수를 가지고 있는 객체가 함수의 인자로 전달될 경우 원본의 객체가 변경될 가능성이 있기 때문 -객체가 함수의 결과로서 반환될 때 • w할당 연산일 경우 함수에서 반환된 값을 저장하는 임시 객체 • 를 생성 자동적으로 이루어져, 프로그래머가 제어할 수 없음 w소멸자 함수가 동적으로 할당된 메모리를 해제하는 경우 장애가 발생할 수 있음

More Related