21
처처처처 처처처 C 처처처처처 제 6 제 C++ 제 제제 처 14 처 처처처처 처처처 처처

처음으로 배우는 C 프로그래밍

  • Upload
    alaqua

  • View
    78

  • Download
    0

Embed Size (px)

DESCRIPTION

처음으로 배우는 C 프로그래밍. 제 6 부 C++ 의 소개 제 14 장 추가적인 클래스 기능. 제 1 절 치환. 치환 (Assignment) 동일 클래스형의 객체간의 치환은 기본적으로 항상 가능하다 . 이때 치환은 내용의 비트별 (bitwise) 복사에 의해 수행된다 . Date a(4, 2, 99), b; b = a; // 비트별 복사에 의한 치환 치환 연산자 operator=( ) - PowerPoint PPT Presentation

Citation preview

Page 1: 처음으로 배우는  C  프로그래밍

처음으로 배우는 C 프로그래밍

제 6부 C++의 소개

제 14 장 추가적인 클래스 기능

Page 2: 처음으로 배우는  C  프로그래밍

2

• 치환 (Assignment)– 동일 클래스형의 객체간의 치환은 기본적으로 항상 가능하다 .– 이때 치환은 내용의 비트별 (bitwise) 복사에 의해 수행된다 .

Date a(4, 2, 99), b;b = a; // 비트별 복사에 의한 치환

• 치환 연산자 operator=( )– 언어에서 기본적으로 제공하는 디폴트 (default) 치환 연산 대신 다른

형태의 치환 연산을 하고자 할때는 치환 연산자를 재정의할 수 있다 .– 치환 연산자의 형태

void operator=(class-name &);

void Date::operator=(Date &newdate){ day = newdate.day; month = newdate.month; year = newdate.year;}

제 1 절 치환

Page 3: 처음으로 배우는  C  프로그래밍

3

• 복사 생성자 (copy constructor)– 생성되는 객체를 기존의 객체로 초기화할 때 사용되는 생성자

– 복사 생성자의 선언 형태class-name(class-name &);

Date(Date &)

– 복사 생성자의 사용예Date a = b; 또는Date a(b);

– 복사 생성자는 객체 선언에서 초기화할 때 이외에 , 함수 인자에 객체를 전달할 때와 , 객체를 함수에서 반환할 때 사용된다 .

– 치환 (assignment) 는 이미 존재하는 객체에 대해서 값을 설정하는 것은 초기화 (initialization) 와는 다르다 .

제 1 절 치환

Page 4: 처음으로 배우는  C  프로그래밍

4

• 베이스 / 멤버 초기화– 생성자의 베이스 / 멤버 초기화 리스트를 사용하여 데이터 멤버를

초기화시킬 수 있다 .

Class Date {

int month, day, year;

public:

Date(int mo = 4, int da = 1, int yr = 96) : month(mo), day(da), year(yr)

{ }

};

제 1 절 치환

Page 5: 처음으로 배우는  C  프로그래밍

5

• 클래스 유효 범위 (scope)

– 데이터 멤버와 멤버 함수 이름은 클래스 유효범위내에 지역적이다 .– 전연 변수 이름이 클래스 내에서 재사용되면 전역 변수는 클래스 데이터

멤버에 의해 은닉된다 .– 멤버 함수는 선언된 클래스에 지역적이고 , 그 클래스로 선언된 객체에

의해서만 사용될 수 있다 .– 멤버 함수의 지역변수는 동일한 이름을 갖는 클래스의 데이터 멤버를

은닉한다 .

제 2 절 추가적인 클래스 특징

Page 6: 처음으로 배우는  C  프로그래밍

6

• 정적 (static) 클래스 멤버– 클래스의 모든 객체들이 공유하는 ( 동일한 저장공간을 갖는 )

데이터 멤버

– 정적 클래스 멤버는 클래스 선언부에서 static 이란 키워드 부가하여 선언하고 , 실제 기억공간을 할당하는 정의는 클래스 밖에 해야 한다 .

Class Employee { private:

static float tax_rate; // 정적 클래스 멤버 선언int id_num;

public:Employee (int);void display( );

};

float Employee::tax_rate = 0.005; // 정적 클래스 멤버 정의

제 2 절 추가적인 클래스 특징

Page 7: 처음으로 배우는  C  프로그래밍

7

제 2 절 추가적인 클래스 특징• 정적 (static) 멤버 함수

– 정적 멤버 만을 접근하는 멤버 함수– 함수 선언시에 static 이란 키워드만 붙이면 정적함수가 된다 .

– 객체가 만들어지기 전에 호출 가능하다 .

Class Employee

{

static float tax_rate; // 정적 멤버public:

Employee(int);

static void disp( ); // 정적 멤버 함수};

void main(void)

{

Employee::disp( ); // 정적 함수 호출 // ...

}

Page 8: 처음으로 배우는  C  프로그래밍

8

• this 포인터 – 멤버 함수를 호출한 객체를 가리키는 포인터– 멤버 함수가 호출될때 자동으로 해당 멤버 함수에 숨겨진 인자로

전달됨

Date::Date(int mm = 7, int dd = 4, int yy = 94){

month = mm; day = dd; year = yy;}

this 포인터를 명시적으로 사용한 멤버함수

Date::Date(int mm = 7, int dd = 4, int yy = 94){

this>month = mm; this> day = dd; this> year = yy;}

제 2 절 추가적인 클래스 특징

Page 9: 처음으로 배우는  C  프로그래밍

9

• 프렌드 (friend) 함수– 클래스의 멤버 함수가 아닌 것 중에서 멤버 함수와 동일한 데이터

멤버 및 멤버 함수에 대한 사용 ( 접근 ) 권한을 갖는 함수– 프렌드 함수의 정의

class Date {int month, day, year;

public:Data(int, int, int);void showdate( );friend int get_month(Data a); // 프렌드 함수 선언

};

int get_month(Data a) // 프렌드 함수로 사용되는 일반 함수{

return a.month;}

제 2 절 추가적인 클래스 특징

Page 10: 처음으로 배우는  C  프로그래밍

10

• 연산자 (operator) 함수– 치환 연산자를 재정의한 것 처럼 C++ 에서는 기존의 연산자를

재정의할 수 있다 .

– 재정의 될 수 있는 연산자• ( ) ( 함수호출 ), [ ] ( 배열의 원소 ), > ( 포인터 ), new, delete

• ++, , ( 단항 음수 부호 ), !( 논리 부정 ), ~( 비트별 보수 ), * ( 역참조 )

• *, /, %, +, ( 산술 연산 )

• <<, >> ( 이동 (shift) 연산 )

• <, <=, >, >=, ==, !=, &&, || ( 논리 연산 )

• &, ^, | ( 비트별 연산 )

• =, +=, =, *=, /=, %=, &=, ^=, |=, <<=, >>=

• , ( 쉼표 )

– 위에 없는 기호에 대해서는 연산자가 재정의 될 수 없다 .

– 새로운 연산자 기호는 생성될 수 없다 .

– C++ 연산자의 우선순위와 결합법칙은 바뀔 수 없다 .

제 3 절 연산자 함수

Page 11: 처음으로 배우는  C  프로그래밍

11

• 연산자 함수 - 계속– C++ 의 내장 데이터형에 대해서는 연산자가 재정의될 수 없다 .

– 단항 연산자가 이항 연산자로 재정의될 수도 없고 , 이항 연산자가 단항 연산자로 재정의될 수 없다 .

– 연산자 함수는 클래스의 멤버이거나 , 적어도 하나 이상의 클래스를 가져야 한다 .

– 연산자 함수는 멤버 함수나 프렌드 함수로 정의된다 .

Class Date {int month, day, year;

public:Date(int, int, int);Date operator+(int); // + 연산자 중복void showdate(void);

};

Date::Date(int mm = 0, int dd = 0; int yy = 0){

month = mm; day = dd; yy = year;}

Date Date::operator+(int days){ Date temp; temp.day = day+days; temp.year = year; temp.month = month; while (temp.day > 30) { temp.month++; temp.day-= 30; } while (temp.month > 12) { temp.year ++; temp.month -= 12; } return temp;}

제 3 절 연산자 함수

Page 12: 처음으로 배우는  C  프로그래밍

12

• 연산자 함수 - 계속

void Date::showdata(void)

{

cout << month << “/” << day << “/” << year;

}

void main(void)

{

Date a(4,1, 99), b;

cout << “The initial data is “;

a.showdate( );

b = a + 284; // b = a.operator+(284); 연산자 함수 호출cout << “\nnew data is “;

b.showdate;

}

제 3 절 연산자 함수

Page 13: 처음으로 배우는  C  프로그래밍

13

제 3 절 연산자 함수• 치환 연산자

– 다중 치환을 위한 치환 연산자 중복• a = b = c; 는 a = (b = c); 와 같이 오른쪽 부터 처리된다 .• 이때 (b = c;) 처리 결과가 a 에 치환되기 때문에 , 치환 연산자 함수의

반환값이 b 에 치환되는 값을 갖는 객체이어야 한다 .

Date operator=(Date &newdate)

{

day = newdate.day;

month = newdate.month;

year = newdate.year;

return *this; // 치환 연산자 함수를 호출하는 객체 자체를 반환 }

Date a(4, 1, 99), b, c;

c = b = a; c.operator=(b.operator=(a));

Page 14: 처음으로 배우는  C  프로그래밍

14

제 4 절 데이터형 변환• 내장형에서 내장형으로 변환

– 예 ) int val = (int) 14.3;

float val2 = float(143);

• 내장형에서 사용자 정의 데이터형 ( 클래스 ) 로의 변환– 형변환 (type conversion) 생성자 사용

Date::Date(long findate) // long 형을 Date 형으로 변환하는 생성자{

year = int (findate/10000.0);

month = int ((findate - year*10000.0)/100.0);

}

Date a;

a = Date(991225); // long 형 값을 Date 형으로 변환하는 문장

Page 15: 처음으로 배우는  C  프로그래밍

15

제 4 절 데이터형 변환• 사용자 정의형 ( 클래스 ) 에서 사용자 정의형으로의 변환

– 형변환 연산자 사용• 형변환 연산자에서 연산자 이름은 변환될 클래스 이름이 된다 .• 예를 들어 , Date 클래스형 객체를 IntDate 클래스형 객체로 변환하고자

하는 경우 , Date 클래스 내에 IntDate 형으로의 형변환 연산자를 선언한다 .

Date::operator IntDate( ) {

// }

• 사용자 정의형에서 내장형으로의 변환– 형변환 연산자 사용

• 형변환 연산자에서 연산자 이름은 변환될 내장형 이름이 된다 Date::operator long( ) {

// }

Page 16: 처음으로 배우는  C  프로그래밍

16

제 5 절 클래스 상속• 상속 (inheritance)

– 어떤 기존 클래스로 부터 새로운 클래스를 파생시키는 것• 기존 클래스 : 베이스 (base) 클래스 / 부모 (parent) 클래스 / 상위 (super)

클래스• 파생된 클래스 : 파생 (derived) 클래스 / 자식 (child) 클래스 / 하위 (sub)

클래스– 파생 클래스는 베이스 클래스의 모든 데이터 멤버와 멤버 함수를

포함하는 완전히 새로운 클래스이다 .

– 파생 클래스에는 그 클래스만의 새로운 데이터 멤버와 멤버 함수를 추가할 수 있으며 , 베이스 클래스의 함수를 재정의할 수도 있다 .

– 두 개 이상의 베이스 클래스를 갖는 , 즉 다중상속하는 파생 클래스도 정의할 수 있다 .

– 파생 클래스 정의class 파생 -클래스 -이름 : 접근명세 베이스 -클래스 -이름

Page 17: 처음으로 배우는  C  프로그래밍

17

제 5 절 클래스 상속• 클래스 내에서의 접근명세 (Access specification)

– private( 전용 ), public( 공용 ), protected( 보호 )

– private 영역내의 멤버• 클래스 멤버 함수나 프렌드 함수에 의해서만 접근 ( 사용 ) 가능• 파생 클래스에서는 베이스 클래스의 private 영역 멤버 사용 불가

– public 영역 내의 멤버• 클래스 멤버든 비멤버든 사용 가능• 파생 클래스에서도 베이스 클래스의 public 영역 멤버 사용 가능

– protected 영역 내의 멤버• 클래스 멤버 함수나 프렌드 함수에 의해서만 접근 ( 사용 ) 가능• 파생 클래스에서는 베이스 클래스의 protected 영역 멤버 사용 가능

Page 18: 처음으로 배우는  C  프로그래밍

18

제 5 절 클래스 상속• 클래스 상속시의 접근 명세

– private• 베이스 클래스의 모든 멤버를 private 영역의 멤버로 간주• 파생 클래스를 통해서 베이스 클래스의 public 영역 멤버의 사용도 불가• 베이스의 private, public, protected 멤버 파생 클래스의 private 멤버

– public• 베이스 클래스의 멤버를 베이스 클래스에서의 접근명세대로 파생 클래스에 상속• 베이스의 private 멤버 파생 클래스의 private 멤버• 베이스의 public 멤버 파생 클래스의 public 멤버• 베이스의 protected 멤버 파생 클래스의 protected 멤버

– protected• 베이스의 private 멤버 파생 클래스의 private 멤버• 베이스의 public, protected 멤버 파생 클래스의 protected 멤버

Page 19: 처음으로 배우는  C  프로그래밍

19

제 5 절 클래스 상속

• 파생 클래스의 예Class Circle // 베이스 클래스{

protected:

double radius;

public:

Circle (double r = 1.0)

{

radius = r;

}

double calval(void)

{

return (pi*radius*radius);

}

};

Class Cylinder : public Circle // 파생 클래스 {

protected:

double length;

public:

Cylinder(double r = 1.0, double l = 1.0):

Circle(r), length(1) { }

double calval (void) ; // 함수 재정의};

double Cylinder::calval(void)

{

return (length*Circle::calval( ));

}

Page 20: 처음으로 배우는  C  프로그래밍

20

제 5 절 클래스 상속

• 다형성 (polymorphism)

– 베이스 클래스와 파생 클래스가 같은 이름의 함수를 가지고 있을 때 , 포인터가 베이스 클래스 객체가 가리킬 때 포인터를 통해 해당 함수를 호출하면 베이스 클래스의 함수가 수행되고 , 포인터가 파생 클래스 객체를 가리킬 때는 파생 클래스의 함수가 수행되도록 하는 것

– 포인터를 통한 동적 바인딩을 위해 이와 같이 다형성을 제공할 함수들은 가상 함수 (virtual function) 로 정의한다 .

– 가상 함수는 멤버 함수 앞에 virtual 이란 키워드만 부여함으로써 가상 함수가 된다 .

Page 21: 처음으로 배우는  C  프로그래밍

21

제 5 절 클래스 상속• 다형성 지원을 위한 가상 함수 사용예

class One { protected: float a; public : One(float); virtual float f1(float); float f2(float);};

One::One(float val = 2) { a = val; }

float One::f1(float num){ return (num/2); }

float One::f2(float num){ return (pow(f1(num),2)); }

class Two: public One { public : virtual float f1(float);};

float Two::f1(float num){ return (num/3); }

void main(void){ One object_1; Two object_2; One *ptr; ptr = &object_1; cout << “object_1” << ptr>f1(12) << endl;

ptr = &object_2; cout << “object_2” << ptr>f1(12 ) << endl; }