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
처음으로 배우는 C 프로그래밍
제 6부 C++의 소개
제 14 장 추가적인 클래스 기능
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 절 치환
3
• 복사 생성자 (copy constructor)– 생성되는 객체를 기존의 객체로 초기화할 때 사용되는 생성자
– 복사 생성자의 선언 형태class-name(class-name &);
Date(Date &)
– 복사 생성자의 사용예Date a = b; 또는Date a(b);
– 복사 생성자는 객체 선언에서 초기화할 때 이외에 , 함수 인자에 객체를 전달할 때와 , 객체를 함수에서 반환할 때 사용된다 .
– 치환 (assignment) 는 이미 존재하는 객체에 대해서 값을 설정하는 것은 초기화 (initialization) 와는 다르다 .
제 1 절 치환
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 절 치환
5
• 클래스 유효 범위 (scope)
– 데이터 멤버와 멤버 함수 이름은 클래스 유효범위내에 지역적이다 .– 전연 변수 이름이 클래스 내에서 재사용되면 전역 변수는 클래스 데이터
멤버에 의해 은닉된다 .– 멤버 함수는 선언된 클래스에 지역적이고 , 그 클래스로 선언된 객체에
의해서만 사용될 수 있다 .– 멤버 함수의 지역변수는 동일한 이름을 갖는 클래스의 데이터 멤버를
은닉한다 .
제 2 절 추가적인 클래스 특징
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 절 추가적인 클래스 특징
7
제 2 절 추가적인 클래스 특징• 정적 (static) 멤버 함수
– 정적 멤버 만을 접근하는 멤버 함수– 함수 선언시에 static 이란 키워드만 붙이면 정적함수가 된다 .
– 객체가 만들어지기 전에 호출 가능하다 .
Class Employee
{
static float tax_rate; // 정적 멤버public:
Employee(int);
static void disp( ); // 정적 멤버 함수};
void main(void)
{
Employee::disp( ); // 정적 함수 호출 // ...
}
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 절 추가적인 클래스 특징
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 절 추가적인 클래스 특징
10
• 연산자 (operator) 함수– 치환 연산자를 재정의한 것 처럼 C++ 에서는 기존의 연산자를
재정의할 수 있다 .
– 재정의 될 수 있는 연산자• ( ) ( 함수호출 ), [ ] ( 배열의 원소 ), > ( 포인터 ), new, delete
• ++, , ( 단항 음수 부호 ), !( 논리 부정 ), ~( 비트별 보수 ), * ( 역참조 )
• *, /, %, +, ( 산술 연산 )
• <<, >> ( 이동 (shift) 연산 )
• <, <=, >, >=, ==, !=, &&, || ( 논리 연산 )
• &, ^, | ( 비트별 연산 )
• =, +=, =, *=, /=, %=, &=, ^=, |=, <<=, >>=
• , ( 쉼표 )
– 위에 없는 기호에 대해서는 연산자가 재정의 될 수 없다 .
– 새로운 연산자 기호는 생성될 수 없다 .
– C++ 연산자의 우선순위와 결합법칙은 바뀔 수 없다 .
제 3 절 연산자 함수
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 절 연산자 함수
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 절 연산자 함수
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));
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 형으로 변환하는 문장
15
제 4 절 데이터형 변환• 사용자 정의형 ( 클래스 ) 에서 사용자 정의형으로의 변환
– 형변환 연산자 사용• 형변환 연산자에서 연산자 이름은 변환될 클래스 이름이 된다 .• 예를 들어 , Date 클래스형 객체를 IntDate 클래스형 객체로 변환하고자
하는 경우 , Date 클래스 내에 IntDate 형으로의 형변환 연산자를 선언한다 .
Date::operator IntDate( ) {
// }
• 사용자 정의형에서 내장형으로의 변환– 형변환 연산자 사용
• 형변환 연산자에서 연산자 이름은 변환될 내장형 이름이 된다 Date::operator long( ) {
// }
16
제 5 절 클래스 상속• 상속 (inheritance)
– 어떤 기존 클래스로 부터 새로운 클래스를 파생시키는 것• 기존 클래스 : 베이스 (base) 클래스 / 부모 (parent) 클래스 / 상위 (super)
클래스• 파생된 클래스 : 파생 (derived) 클래스 / 자식 (child) 클래스 / 하위 (sub)
클래스– 파생 클래스는 베이스 클래스의 모든 데이터 멤버와 멤버 함수를
포함하는 완전히 새로운 클래스이다 .
– 파생 클래스에는 그 클래스만의 새로운 데이터 멤버와 멤버 함수를 추가할 수 있으며 , 베이스 클래스의 함수를 재정의할 수도 있다 .
– 두 개 이상의 베이스 클래스를 갖는 , 즉 다중상속하는 파생 클래스도 정의할 수 있다 .
– 파생 클래스 정의class 파생 -클래스 -이름 : 접근명세 베이스 -클래스 -이름
17
제 5 절 클래스 상속• 클래스 내에서의 접근명세 (Access specification)
– private( 전용 ), public( 공용 ), protected( 보호 )
– private 영역내의 멤버• 클래스 멤버 함수나 프렌드 함수에 의해서만 접근 ( 사용 ) 가능• 파생 클래스에서는 베이스 클래스의 private 영역 멤버 사용 불가
– public 영역 내의 멤버• 클래스 멤버든 비멤버든 사용 가능• 파생 클래스에서도 베이스 클래스의 public 영역 멤버 사용 가능
– protected 영역 내의 멤버• 클래스 멤버 함수나 프렌드 함수에 의해서만 접근 ( 사용 ) 가능• 파생 클래스에서는 베이스 클래스의 protected 영역 멤버 사용 가능
18
제 5 절 클래스 상속• 클래스 상속시의 접근 명세
– private• 베이스 클래스의 모든 멤버를 private 영역의 멤버로 간주• 파생 클래스를 통해서 베이스 클래스의 public 영역 멤버의 사용도 불가• 베이스의 private, public, protected 멤버 파생 클래스의 private 멤버
– public• 베이스 클래스의 멤버를 베이스 클래스에서의 접근명세대로 파생 클래스에 상속• 베이스의 private 멤버 파생 클래스의 private 멤버• 베이스의 public 멤버 파생 클래스의 public 멤버• 베이스의 protected 멤버 파생 클래스의 protected 멤버
– protected• 베이스의 private 멤버 파생 클래스의 private 멤버• 베이스의 public, protected 멤버 파생 클래스의 protected 멤버
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( ));
}
20
제 5 절 클래스 상속
• 다형성 (polymorphism)
– 베이스 클래스와 파생 클래스가 같은 이름의 함수를 가지고 있을 때 , 포인터가 베이스 클래스 객체가 가리킬 때 포인터를 통해 해당 함수를 호출하면 베이스 클래스의 함수가 수행되고 , 포인터가 파생 클래스 객체를 가리킬 때는 파생 클래스의 함수가 수행되도록 하는 것
– 포인터를 통한 동적 바인딩을 위해 이와 같이 다형성을 제공할 함수들은 가상 함수 (virtual function) 로 정의한다 .
– 가상 함수는 멤버 함수 앞에 virtual 이란 키워드만 부여함으로써 가상 함수가 된다 .
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; }