상속이란 객체의 특성을 물려받는 개념이다.
상속의 대표적 관계
#is-a 관계 : 아주 지극히 당연한 관계조건이다. ~~는 ~이다 라는 조건하에 이루어지는 상속으로 상위 클래스를 상속할경우 기능과 특성이 세밀해지며 작은 단위의 클래스를 형성할수 있게된다.
예)
- 경찰은 사람이다. : 경찰이 사람 클래스를 상속하는 경우.
- 자동차는 기계이다. : 자동차가 기계클래스를 상속하는경우.
등등...
#has-a 관계 : 소유적 관계이며 is-a 관계와는 또다른 상속의 개념이다. 상속 키워드를 사용해서 상속하는방법 뿐만이 아니라 맴버데이터로 객체나 포인터객체를 사용함으로써 포함하는 관계를 성립할수도 있다는 것이다.
예)
- 경찰은 권총을 소유한다. : 경찰 클래스내 데이터에 권총 클래스의 객체를 생성하는 경우.
등등...
대략.. 많은 경험이 없기때문에 여기까지 떠들고 코딩하러감 ㅇㅅㅇ
'c++'에 해당되는 글 21건
- 상속관계 (1) 2008/05/23
- 문자관련 함수 라이블러리 // ctype.h 2008/04/23
- 복사 생성자 , c++ style....; 2008/04/17
- oop만의 특징 클래스와 객체 (4) 2008/04/09
- c++ 레퍼런스 (2) 2008/04/01
| 함수 이름 | 리턴 값 |
|
isalnum() |
전달인자가 영문자이거나 숫자일경우 true값을 반환한다. |
| isalpha() | 전달인자가 영문자[소문자 + 대문자] 일경우 true값을 반환한다. |
| isdigit() | 전달인자가 숫자[0~9] 일경우 true값을 반환한다. |
| isxdigit() | 전달인자가 16진수[0~9 , a~f , A~F]이면 true를 반환한다. |
| islower() | 전달인자가 소문자[a~z] 일경우 true값을 반환한다. |
| isupper() | 전달인자가 대문자[A~Z] 일경우 true값을 반환한다. |
| ispunct() | 전달인자가 구두점일경우 true값을 반환한다. |
| isspace() | 전달인자가 화이트스페이스[공백,엔터,케리지리턴,수평탭,수직탭,용지이송] 일경우 true값을 반환한다. |
| iscntrl() | 전달인자가 제어문자일경우 true값을 반환한다. |
| isascii() | 전달인자가 아스키코드일경우 true값을 반환한다. |
| isgraph() | 전달인자가 빈칸이 아닌 인쇄할 수 있는 문자일경우 true값을 반환한다. |
| isprint() | 전달인자가 인쇄가능한 문자일경우 true값을 반환한다. |
| tolower() | 전달인자가 대문자이면 소문자로 바꾸어서 리턴한다. 그렇지 않을경우 그냥 리턴한다. |
| toupper() | 전달인자가 소문자이면 대문자로 바꾸어서 리턴한다. 그렇지 않을경우 그냥 리턴한다. |
위 함수들은 매우 활용적이다 가령
if((ch >= 'a' || ch <= 'z') || (ch >= 'A' || ch<= 'Z')) 이런 조건문은 if(isalpha()) 라고 표시하는것과 전혀 다르지 않으며 프로그램의 가독성을 향상시켜줄수 있다.
cctype라이블러리의 함수를 사용한 예제
댓글을 달아 주세요
C 초기화 스타일.
C++ 초기화 스타일.
시작부터 왠 잡설 -ㅅ-? 하는데 이런 형식의 초기화를 사용하여 객체를 복사할수 있다.
미리 생성한 객체와 나중에 생성한 객체가 같은 값을 가지길 원한다면 아래와 같이 코딩해보쟈 ㅋㅋ
using std::cout;
using std::endl;
class test{
int x;
int y;
public:
test(int _x , int _y){ //생성자.
x = _x;
y = _y;
}
test(test & copy){ //복사 생성자.
x = copy.x;
y = copy.y;
}
void print(){
cout<<"x = "<<x<<endl
<<"y = "<<y<<endl;
}
};
int main(){
test p1(5,10);
p1.print();
test p2(p1);
p2.print();
return 0;
}
c-b-r에 대해 배웠다면 무슨의미인지 눈에 확연히 들어올거다. 중요한건 레퍼런스에 의해 주소값이 복사된 객체의 맴버데이터를 생성자에서 대입하고 있는것이다. 이렇게 맴버데이터별 대입을 하면 이전 객체와 나중 객체가 같은 값을 갖게된다. 물론 주소는 다르겟지만;
잡설:컴파일러는 클래스 내에서 생성자또는 소멸자가 없을경우 디폴트 생성자와 소멸자를 자동으로 제공해준다. 그렇다면 복사 생성자도 마찬가질까?... ㅇㅅㅇ 마찬가지다 ㅋ
using std::cout;
using std::endl;
class test{
int x;
int y;
public:
test(int _x , int _y){ //생성자.
x = _x;
y = _y;
}
void print(){
cout<<"x = "<<x<<endl
<<"y = "<<y<<endl;
}
};
int main(){
test p1(5,10);
p1.print();
test p2(p1);
p2.print();
return 0;
}
댓글을 달아 주세요
과거 절차지향적인 프로그래밍 언어가 문제를 풀기에 중점을 둔 언어 였다면 oop(객체 지향 프로그래밍)으로 언어가 거듭 바뀌면서 많은 프로그래머들은 생각하는 방식을 바꿔야만 했다. 나 또한 아직 클래스,객체의 완전한 의미와 왜 이렇게 사용해야만 하는가가 확 와닿진 않지만 아마도 좀더 많은 라인의 코드를 짜다보면 알지도 모르겟다 ㅋㅋ;;
클래스를 설명하기 앞서 객체의 개념을 설명해본다.
객체지향의 개념을 갖고 나온것이 C++이다. 왜 그렇게 객체.. 객체 하는걸까? 생각해보면 여러가지 이유가 있겟지만 나는 이렇게 생각한다.
"현실세계에 있는 사물을 그대로 모델링해서 프로그램으로 옮긴다."
객체란 말은 사전적의미 + 네이버 지식인빠돌이들의 답변을 종합하면 어떤 사물의 완성된 상태라고 정리가 되는데 이 상태는 두가지 분류로 나눌수있다. 하나는 사물의 데이터이고 다른 하나는 사물이 하는 행위이다. 이런 데이터와 행위를 하나로 묶어 자료를 만들고 이런 자료를 토대로 만들어낸 것이 바로 객체이다. 그리고 이렇게 사물의 특징을 통해 자료를 추출해 내는 행위를 데이터 추상화라고 한다.
그렇다면 추상화는 어떻게할까?
현실에 존재하는 사물을 하나 예로 들어보자. 고양이가 있다고 하면 이 고양이를 추상화 시킬때 필요한것은 고양이가 갖고있는 데이터와 행위를 묶어내면 이것은 프로그래밍에 사용되는 완전한 고양이가 되는것이다. 고양이의 데이터로는 고양이의 몸무게,길이,색 등이 있겟고 고양이의 행위는 울기,걷기,뛰기,먹기 등.. 많은 행위가 있다.
이것들은 모두 고양이에 관한 자료를 추상화한것이다.
그렇다면 객체란??
추상화된 자료를 토대로 만들어낸것이 객체이지만 현실의 사물을 완벽한 모습의 프로그램 코드로 작성하는것이 더 올바른 정의가 되겟다.
이제 클래스의 개념을 설명해본다.
클래스를 설명하기전에 C언어의 구조체에 관해 약간 언급할 필요가있다. 구조체의 특징은 여러가지 복합된 자료형을 하나로 묶어주는 매우 탁월한 기능을 갖고있지만 자료형만으로는 사물을 완벽히 구현해 낼 수 없다. 하지만 c++로 넘어오면서 구조체는 몇가지 장점을 더 갖고 왔는데 그중 하나가 구조체 맴버에 함수를 포함시킬수 있는것이다. 함수를 포함하는것은 그야말로 oop를 완전히 구현하겟다는 의미이다. 왜냐면 추상화된 데이터에는 분명 행위가 존재하기때문이다. 그렇다면 왜 클래스에관해선 설명을 하지않는가? 물론 클래스라는 새로운 개념이 도입되어 좀더 효과적으로 자료를 관리할수 있겟지만 구조체도 자세히 알지못하는 프로그래머가 어떻게 클래스를 다룰까? 클래스와 구조체는 단 1가지 차이점을 빼고는 완전히 동일하다. "클래스⊃구조체" 내가 설명하고 싶은것은 이것이다.
이제 본론으로 ㅋㅋ
위에서 어떤 사물의 데이터를 추상화 했다. 이렇게 사물의 자료를 모으는것 만으로는 객체를 만들 수 없다. 사물의 자료가 여러군대에 너저리 하게 널려있을경우 그것 한대 뭉쳐야만 비로소 객체를 만들수 있기 때문이다.
이렇듯 추상화된 자료를 코드로 옮기기위해선 클래스나 구조체를 통해 자료형으로 묶어줘야하는데 이를 클래스화 라고 한다.
그렇다면 어떻게 클래스화 할까?
어떤 추상화된 사물의 데이터를 묵어주기만 하면된다. 가령 고양이의 특징을 모두 묶어줄경우 이를 클래스화라고 한다. 하지만 추상화를 통하지 않고도 클래스화가 가능한 사례가 있다.
레시피가 그중 하나인데 이를 클래스와 비교해볼경우 레시피에는 음식에 필요한 재료(데이터)와 어떻게 조리하면 음식이 된다(행위) 가 적혀있다. 이는 완성된 객체와는 확연히도 다르다. 바나나의 객체를 역추적하면 추상화된 자료를 이해할수 있겟지만 음식의 경우는 좀 다르다^^;; 이런건 뭐라고 의미짓는지 모르겟네;;
설명을 이어나가보자 ㅋㅋ
그런데 이렇게 레시피만 잇을때 우리는 음식을 먹을수있을까? 그럴수없다. 물론 너무 배고파서 레시피를 씹어먹을수도잇지만.. ㅈㅅ; ㅋㅋ 아무튼 레시피에 적혀있는것을 그대로 따라할때 음식이라는 객체가 탄생된다.
클래스와 객체의 관계는...
사물의 자료를 모두 추출해서 모아놓은 자료를 묶어 클래스라하고 이 클래스를 통해 만든 변수를 객체라고 한다.
이렇게 객체를 만들어내는 행위를 "인스턴스화" 또는 "객체화" 라고한다. 물론 언어적 의미로 차이가 있듯이
인스턴스화와 객체화는 분명 배경적 의미가 조금은 다를거라 생각된다.
???
구조체로 묶을경우 구조체변수라 하는데 왜 클래스로 묶을경우 객체라 하는가? 이는 나도 잘모르겟다. 사실 구조체에도 함수를 포함할수있기때문에 완벽한 객체를 만들어 낼 수 있을거 같은데..; 뭔가 내가 모르는 또하나의 요소가 있을지도..;
구조체 = 클래스. why? 변수+함수로 묶어서 정의가능.
왜 클래스는 함수 + 변수인가...
데이터 추상화 과정을 하다보면 데이터가 있지만 기능부분도
함께 추상화 되기때문이다.
그렇다면 클래스 변수는 왜 객체인가?
데이터 + 기능을 통해 형성된 변수는 현실세계에 존재하는것과
같은 완벽한 대상체 즉 객체가 된다
댓글을 달아 주세요
-
강철지크
2008/04/10 15:16
address
modify / delete
reply
오 오브젝트 오리엔티드 프로그램인가요?
3년을 컴퓨터 학과에 다녔건만 남은건 뭐가 있는지... -
yhstory
2008/04/11 19:45
address
modify / delete
reply
ㅋㅋㅋ
우선적으로 구조체와 클래스는 서로 완전히 다른 개념으로 설명하기 때문에 비교하기 애매한점이 있고ㅋ
(비교안하거나 못할순 없음, 순전히 개인의 자유이므로)
궂이 비교해보자면 상속을 한번 생각해보시게 ㅋ
구조체 상속? 응?
그리고 아직 다른언어들을 안배워서 c와 c++의 차이점으로
구조적 프로그래밍과 객체지향적 프로그래밍을 이해하려는 경향이 있는것 같은데~
그래서는 안된다는 것!
시간나는대로 틈틈히 자바를 한번 해보는것이 객체지향이란 개념의
이해해 큰 도움이 될것 같다~
그리고 언어의 차이에 너무 집중할 필요는 없다~
언어는 표현 도구일 뿐이라는 것
프로그래밍은 언어로 작성하는 코딩의 과정이 아니라
문제해결을 위한 사고과정쯤? 그걸 언어로 표현할 뿐이지(왼손은 거들뿐-.-;;)
그리고 군대가기전에 win api정도까지는 보고가라~
언제가는지는 몰라도~ㅋ
by 영화
레퍼런스는 c++에서 새로 도입된 개념이다. 레퍼런스란 변수명을 갖고있는 메모리주소에 또하나의 변수명을 지어주는것과 같다. 그렇다면 변수란 무엇일까? 그냥 변하는 값, 또는 상수,변수를 대입할수있는 이름 정도로 생각하는것은 안된다. 물론 그런 의미에서 변수일지몰라도 레퍼런스를 이해하려면 한가지 개념을 더 숙지해야만한다.
변수란 "메모리주소에 접근하기위해 사용자가 직접 정해준 이름" 라고 한가지 더 정의하겟다.
레퍼런스란말은 c언어에서 "Call-by-value" 를 배울때 가치 텨나온 개념중 "Call-by-Reference " 에서 레퍼런스의 말과 같다. 물론 완벽하게 같진 않지만 하는 행위는 비슷하다.
Call-by-Reference : 함수 에서 함수로 값을 넘겨줄때 값이 아닌 주소를 복사하여 넘겨주는 방식
위에서 레퍼런스에 관해 많이도 언급햇는데 그럼 어떻게 사용하느냐?
&를 이용하여 레퍼런스를 선언하면된다. 시작부터 &기호를 통해 선언이라고 말하면 좀 이해가 안될수도 있어서 포인터와 견주어 설명해볼까함.
int * pt; : int형 pt를 선언하되 앞에 * 연산자를 붙임으로써 int형 포인터 변수를 선언한것과 같다.
그렇다면 &를 어디에 사용하는지도 짐작이 갈것이다.
int & val; : int형 레퍼런스 val을 선언한것이다.
그럼 어디에 쓰느냐? 바로 메모리주소에 이름을 달아줄때 쓴다. 그럼 여기서 바로 의문점이 생긴다. 어디에 있는 메모리주소에 이름을 달아줄것인가..?;; 답은 미리 선언된 변수명을 갖고있는 메모리주소에 해주는것이다. 즉, 레퍼런스를 선언하기전에 무조건 변수를 선언해야만 한다.
-선언과 즉시 초기화 해줘야만한다.
-상수로 초기화 할수없다. 이유는 즉, 상수는 메모리주소를 갖고있지 않기때문이다. 변수를 int 10으로 만드는넘은없다 -ㅅ-;
간단한 레퍼런스의 예제
using std::cout;
using std::endl;
int main(){
int val=0;
int &ref = val; //레퍼런스 초기화
val++;
ref++;
cout<<val<<endl
<<ref<<endl;
return 0;
}
코드 해석 : int형의 크기를 가진 메모리를 할당후 val라는 이름을 붙여주었다. 그리고 그 메모리에 다시 ref라는 이름을 붙여준것이다. val과 ref는 같은 메모리를 가르키고 있다. 같은 메모리주소를 가르키고 있기때문에 val가 값을 증가시키던 ref가 값을 증가시키던 출력되는 값은 항상 같다.
그렇다면 레퍼런스와 변수명은 차이가 없는걸까? 딱짤라서 없다 ㅋㅋㅋ;; 만드는 과정에서 차이만 날뿐 그후엔 100% 동일한 변수명으로 움직인다.
레퍼런스는 Call-by-Reference를 구현함에 있어서 꽤나 쉽게 구현이 가능하다.
using std::cout;
using std::endl;
void swap(int &,int &);
int main(){
int a=10, b=20;
cout<<"swap 전"<<endl
<<"a = "<<a<<endl
<<"b = "<<b<<endl<<endl;
swap(a,b);
cout<<"swap 후"<<endl
<<"a = "<<a<<endl
<<"b = "<<b<<endl;
return 0;
}
void swap(int & x , int & y){
int temp = x;
x = y;
y = temp;
}
일단 포인터를 사용하지않고도 동일한 메모리주소를 가질수있다는점이 매우 유용하다. c언어에 포인터가 있어 사용한다고는 하지만 포인터를 많이 사용하는 프로그램이 꼭 좋은 프로그램일리는 없다. 또한 Call-by-value의 값복사 방식을 취하지 않고서도 값의 접근이 가능해서 매우 안전한거같다.
하지만 레퍼런스를 이용한 Call-by-Reference에도 단점은 있다. 바로 인자값의 오해이다. 함수 호출시 인자값을 넘겨줄때 &를 취하지않고 넘겼을경우 그것이 값을 복사하는 벨류방식인지 주소를 복사하는 레퍼런스방식인지 햇갈리기때문이다. 또하나의 단점은 리턴타입의 문제이다.
using std::cout;
using std::endl;
int & add(void);
int main(){
int &ref = add();
cout<<ref<<endl;
return 0;
}
int & add(void){
int val=10;
return val;
}
스텍에 할당된 메모리는 블록구조에 의해
블록이 끝날때 메모리가 해제되는것쯤은 다 아는 사실이다. 그렇다면 add함수에서 할당된 val메모리는 메인함수까지가서 존재하는것일까? 확실히 저 코드를 컴파일해서 실행하면 정확한 값이 출력되긴 하지만 저런 예제와 비슷한 코드가 만일 수천줄의 다다르는 코드라면 절대로 원하는 값을 보장받기는 힘들것이다.
암튼 이렇게나마 공부해 두길 망정이지 계속해서 모르는 부분이 쌓인다면 앞으로 더 힘들어질것같다. ㅋㅋ 하지만 걱정엄다는거! ㅎㅎ
댓글을 달아 주세요
-
강철지크
2008/04/08 04:31
address
modify / delete
reply
나름 블로그를 DB화 하시는군요.
좋은 습관이십니다.
엑셀 파일로 정리해두는 것도 좋다고 하더군요.
각종 공부와 업무들을 기록해서 일지로 보관하기도 하구요.
암튼 화이팅입니다 !!

댓글을 달아 주세요
제피트할아버지는 피노키오를 소유한다.
피노키오는 큰코를 소유한다.
제피트할아버지는 큰 코를가진 피노키오를 소유하므로
이중상속인가요?