===========================================================
* 객체지향프로그래밍I (C++)
Class설계, 상속, 함수 중복정의(오버로딩), 연산자 중복, 다형성
Object-Oriented Programming
ㄴ C언어 기반으로 만들어낸 객체지향 언어
ㄴ ( if, for, while, switch case문, 기본데이터형( int, double, float, char, string ) )을 그대로 사용함
* 출력
std::cout <<출력대상(문자, 숫자, 문자열, 포인터, 배열, 함수);
* 객체지향언어의 특성
[ 함수 중복(함수 오버로딩) ]
ㄴ 함수이름을 중복해서 선언할 수 있다.
ㄴ 확장자가 .cpp일 경우 에러가 나지 않음, .c로 확장자 변경시 에러남 (C언어는 함수 호출 시 함수 이름을 보고 호출을 하기 때문)
ㄴ 단, 매개변수 정보가 달라야 한다. (매개변수 갯수, 매개변수 타입)
ㄴ C++ 에서는 함수호출 할 때 함수이름+매개변수 정보로 호출
int sum(int a=0. int b=0. int c=0)
{ return a+b+c; }
---------------------------------------------------------
sum();
sum(10);
sum(10, 20);
sum(10, 20, 30); //결과 모두 돌아감
[디폴트 매개변수]
ㄴ 함수의 매개변수가 디폴트 값을 가질 수 있다.
ㄴ 디폴트 매개변수를 적절히 활용하면 함수 오버로딩한 효과를 낼 수 있다.
int sum(int a=0. int b=0. int c=0)
{ return a+b+c; }
---------------------------------------------------------
sum();
sum(10);
sum(10, 20);
sum(10, 20, 30); //결과 모두 돌아감
[ 참조 = 레퍼런스 (Reference) ]
: 이름을 지니는 공간에 별명(별칭)을 붙여주는 것
만드는 방법은 변수 선언과 다르지만
만든 후 사용 방법은 변수와 같다. 데이터형 &레퍼런스명 = 대상;
int num = 10;
num++;
std::cout<<num;
int &ref1 = num;
ref1++;
std::cout<<ref1;
int &ref2 = ref1; //ref1 혹은 num 둘 다 가능
ref2++;
std::cout<<ref2;
std::cout<<num<<' '<<ref1<<' '<<ref2; //값이 모두 동일하게 출력됨
std::cout<<&num<<' '<<&ref1<<' '<<&ref2; //위치 값이 모두 동일하게 출력됨
---------------------------------------------------------------------------
1) char temp = 't';
char temp2 = temp;
2) char temp = 't';
char &temp2 = temp;
= 둘의 차이는 1은 둘의 주소가 다르지만, 2는 주소값이 같다.
---------------------------------------------------------------------------
[ 참조와 함수 (Call by reference) ]
ㄴ 호출할 때 swap(num1, num2); //call by value, call by reference(참조)
swap(&num1, &num2); //call by reference(포인터)
ㄴ 참조, 포인터를 이용한 call by reference에서는 외부에서 값 변경이 가능
(Call by Value, Call by Reference 코드)
#include <iostream>
//두 값을 교환하는 함수 swap() 오버로딩
void swap(int n1, int n2);
void swap(int* n1, int* n2);
int main(void)
{
int num1 = 10, num2 = 20;
swap(num1, num2); //call by value
std::cout << num1 << ' ' << num2 << std::endl; //10 20 (Call by value는 지역변수로 값이 변하지 않음)
swap(&num1, &num2); //call by reference(포인터)
std::cout << num1 << ' ' << num2 << std::endl; //20 10 (위치값을 바꾸었으므로 값이 바뀜)
return 0;
}
void swap(int n1, int n2)
{
int temp = n1;
n1 = n2;
n2 = temp;
}
void swap(int* n1, int* n2)
{
int temp = *n1;
*n1 = *n2;
*n2 = temp;
}
(함수중복, 디폴트 매개변수, 참조 코드)
// [ 함수중복 ]
// - 확장자가 .cpp일 경우 에러가 나지 않음, .c로 확장자 변경시 에러남
#include <iostream>
int sum(int a, int b)
{
return a + b;
}
int sum(int a, int b, int c)
{
return a + b + c;
}
int main(void)
{
int num1 = 10, num2 = 20, num3 = 30;
int result = sum(num1, num2);
std::cout << result; //printf("%d", result);
std::cout << std::endl << std::endl; //printf("n");
result = sum(num1, num2, num3);
std::cout << result;
return 0;
}
// [ 디폴트 매개 변수 ]
#include <iostream>
int sum(int a, int b)
{
return a + b;
}
int sum(int a, int b, int c = 0)
{
return a + b + c;
}
int main(void)
{
int num1 = 10, num2 = 20, num3 = 30;
int result = sum(num1, num2);
std::cout << result; //printf("%d", result);
std::cout << std::endl << std::endl; //printf("n");
result = sum(num1, num2, num3);
std::cout << result;
return 0;
}
// [ 참조변수 (참조, 레퍼런스, reference) ]
#include <iostream>
int main(void)
{
int num = 10;
num++;
std::cout << num;
//레퍼런스 ref1을 부여
int& ref1 = num;
ref1++;
std::cout << ref1;
//레퍼런스 ref2를 부여
int& ref2 = ref1;
ref2++;
std::cout << ref2;
std::cout << std::endl;
std::cout << num << ' ' << ref1 << ' ' << ref2 << std::endl;
std::cout << &num << ' ' << &ref1 << ' ' << &ref2 << std::endl;
return 0;
}
#########
[ 실습1 ] 함수 오버로딩을 이용해서 다음 세 개의 함수를 구현하시오.
int big(int a, int b); //둘 중 큰 값 리턴
int big(int a[], int size); //배열에 저장된 값 중 최대값 리턴
int big(int a, int b, int c); //세개의 값 중 가장 큰 값 리턴
int main(void)
{
int num1 = 10, num2 = 20, num3 = 30;
int arr[5] = { 7, 8, 10, 50, 4 };
int result = big(num1, num2);
std::cout<<result;
result = big(arr, 5);
std::cout<<result;
result = big(num1, num2, num3);
std::cout<<result;
return 0;
}
코드
//###[실습1] 함수 오버로딩을 이용해서 다음 세 개의 함수를 구현하시오.###
//int big(int a, int b); //둘 중 큰 값 리턴
//int big(int a[], int size); //배열에 저장된 값 중 최대값 리턴
//int big(int a, int b, int c); //세개의 값 중 가장 큰 값 리턴
#include <iostream>
int big(int a, int b);
int big(int a[], int size);
int big(int a, int b, int c);
int main(void)
{
int num1 = 10, num2 = 20, num3 = 30;
int arr[5] = { 7, 8, 10, 50, 4 };
int result = big(num1, num2);
std::cout << result << std::endl;
result = big(arr, 5);
std::cout << result << std::endl;
result = big(num1, num2, num3);
std::cout << result << std::endl;
return 0;
}
int big(int a, int b) //둘 중 큰 값 리턴
{
if (a > b)
return a;
else
return b;
}
int big(int a[], int size) //배열에 저장된 값 중 최대값 리턴
{
int maxnum = a[0];
for (int i = 0; i <= size; i++)
{
if (maxnum <= a[i])
{
maxnum = a[i];
}
}
return maxnum;
}
int big(int a, int b, int c) //세개의 값 중 가장 큰 값 리턴
{
int maxnum = 0;
if (a > maxnum)
maxnum = a;
if (b > maxnum)
maxnum = b;
if (c > maxnum)
maxnum = c;
return maxnum;
}
[ 실습2 ] 디폴트 매개변수 이용해서 첫번째, 세번째 big 함수를 하나로 구현하시오.
코드
//###[ 실습2 ] 디폴트 매개변수 이용해서 첫번째, 세번째 big 함수를 하나로 구현하시오.###
#include <iostream>
int big(int a[], int size);
int big(int a = 0, int b = 0, int c = 0)
{
int maxnum = a;
if (c == 0)
{
if (b > maxnum)
maxnum = b;
return maxnum;
}
else
{
if (b > maxnum)
maxnum = b;
if (c > maxnum)
maxnum = c;
return maxnum;
}
}
int main(void)
{
int num1 = 10, num2 = 20, num3 = 30;
int arr[5] = { 7, 8, 10, 50, 4 };
int result = big(num1, num2);
std::cout << result << std::endl;
result = big(arr, 5);
std::cout << result << std::endl;
result = big(num1, num2, num3);
std::cout << result << std::endl;
return 0;
}
int big(int a[], int size) //배열에 저장된 값 중 최대값 리턴
{
int maxnum = a[0];
for (int i = 0; i <= size; i++)
{
if (maxnum <= a[i])
{
maxnum = a[i];
}
}
return maxnum;
}
#########
int num = 10;
[ 메모리 동적할당 / 해제 ] //동적할당(실행 시 할당되었다가 해제시 사라짐)
int * ptr = new int; //new는 동적할당 키워드(연산자) 뒤에는 자료형 선언
double * dptr = new double;
char * cptr = new char;
*ptr = 10; //공간 할당 (10만큼)
delete ptr; //해제함수 (동적할당된 대상이 변수임)
+++C언어에서의 배열 동적할당/해제
int * ptr1 = new int[5]; //heap영역에 동적할당으로 int형 배열 size5만큼 할당하였음(주소가 ptr에 저장됨)
for(int i = 0; i < 5; i++)
{
ptr1[i] = i*10;
}
delete [] ptr1; //해제함수 (중간에 인덱스 연산자 사용), (동적할당된 대상이 배열임)
[ 캡슐화 ]
; 데이터를 캡슐로 싸서 외부의 접근으로부터 보호
ㄴ C++에서 클래스(class 키워드)로 캡슐 표현
[ 클래스와 객체 ]
//C언어에서의 사용자 정의 자료형(구조체)
struct Student
{
char name[30];
int age;
int score;
};
struct Student kim = { "kim", 20, 100 };
//C++에서의 클래스
class 클래스명
{
public:
char name[30];
int age;
int score;
void Study(){ }
void Sleep(){ }
void Work(){ } //자료형 안에 기능이 구현되는 함수도 넣을 수 있음
}; //정의가 끝나면 세미콜론이 반드시 들어감
Student kim( "kim", 20, 100 ); //데이터만 넣었으나 사실상 기능도 들어가 있음
//C++ 다른 예시 (캡슐화 + 데이터 은닉)
class Accout
{
private:
char name[20];
int accnum;
int pwd;
int balance; //잔액
public:
void Deposit(){ } //입금기능
void Withdraw(int money){ balance -= money; } //출금기능
};
Account car( "kim", 1234, 4321, 1000000 );
-> 외부접근 : car.balance -= 500000; //private로 인해 에러남
-> 내부접근 : car.Withdraw(500000); //출금함수를 사용하였으므로 에러발생X
= C와 C++의 차이는 C는 데이터만 캡슐화 가능하지만, C++은 데이터뿐 아니라 기능 구현한 함수까지 캡슐화할 수 있음
[ 상속 ]
; 자식이 부모의 유전자를 물려 받는 것과 유사
//예시
class Person
{
public:
void Sleep(){ }
};
class Student : public Person //상속해서 Person의 기능을 물려받아 사용함
{
public:
void Study(){ }
};
class PartTimeStd : public Student //상속해서 Person과 Student기능 모두 물려받음
{
public:
void Work();
}
Person kim; kim.Sleep();
Student lee; lee.Sleep(); lee.Study();
PartTimeStd park; park.Sleep(); park.Study(); park.Work();
//상속별 가능 기능
[ 다형성 ]
; 하나의 기능이 경우에 따라 다르게 보이거나 다르게 작동하는 현상
ㄴ 연산자 중복, 함수 중복, 함수 재정의(overriding)
* iostream 헤더파일 : c언어 stdio.h 파일과 유사 (printf(), scanf())
1) 표준 입출력 위한 클래스, 객체, 변수, 연산자
namespace std
{
istream --> cin
ostream --> cout
endl
}
2) cout 객체 이용 출력
ㄴ std::cout<<출력대상;
ㄴ 출력대상 : 배열, 변수, 상수, 함수
ex) std::cout<<num1<<' '<<num2<<std::endl;
ex) std::cout<<swap(a,b);
char name[20];
strcpy(name, "홍길동");
std::cout<<name;
int num = 10; int * ptr = #
std::cout<<ptr<<' '<<num;
-> 사용시 cout만 사용하면 X
-> :: (범위지정 연산자), << (삽입연산자)
3) cin 객페 이용 출력
ㄴ std::cin>>입력대상 (변수, 배열, 포인터변수)
ex) std::cin>>num1>>num2; //20 30 (스페이스, tab, Enter 로 구분하여 데이터를 num1, num2에 넣음)
-> :: (범위지정 연산자), >> (추출연산자)
ㄴ 문자열 입력시 공백 허용하고 싶은 경우 해결책
ex) cin.getline(입력대상, 크기(배열의 사이즈), '\n');
#########
[ 실습1 ] 이름, 전공, 나이 입력 후 출력 (공백 없이)
이름을 입력하세요 : 홍길동
전공을 입력하세요 : 컴퓨터공학
나이를 입력하세요 : 33
당신은 컴퓨터공학 33살 홍길동 이군요
#########
* std안에 있는 cout, cin, endl 그냥 접근 사용하는 방법
-> using namespace std;
using std::cout;
using std::cin;
using std::endl;
[ 문자열 공백 입력 ]
ㄴ cin.getline(입력대상, 크기(배열의 사이즈), '\n');
ㄴ getline(cin, 객체명, '\n'); //string객체 사용시
#########
[ 실습1 ] 했던 소스코드를 string객체로 바꾸어 코딩 완성
코드
//[ 실습1 ] 했던 소스코드를 string객체로 바꾸어 코딩 완성
#include <iostream>
#include <string>
using namespace std;
int main(void)
{
string name;
string major;
int age = 0;
cout << "이름을 입력하세요 : ";
getline(cin, name, '\n');
cout << std::endl;
cout << "전공을 입력하세요 : ";
getline(cin, major, '\n');
cout << std::endl;
cout << "나이를 입력하세요 : ";
cin >> age;
cout << std::endl;
cout << "당신은 " << major << ' ' << age << "살 " << name << " 이군요!" << endl;
return 0;
}
[ 실습2 ] 강의자료 맨뒤 C코드를 C++로 바꾸어 코딩 완성(가능하면 main만 가지고 코딩)
코드
//[ 실습2 ] 강의자료 맨뒤 C코드를 C++로 바꾸어 코딩 완성(가능하면 main만 가지고 코딩)
#include <iostream>
using namespace std;
int sum(int startn, int finnum);
int main(void)
{
int finnum = 0;
int n = 0;
cout << "끝 수를 입력하세요 : ";
cin >> finnum;
cout << "1에서 " << finnum << "까지의 합은 " << sum(1, finnum) << "입니다." << endl;
return 0;
}
int sum(int startn, int finnum)
{
int result = 0;
for (int i = startn; i <= finnum; i++)
{
result += i;
}
return result;
}
#########