6.1 함수 중복
함수 중복은 다형성의 한 사례
조건
1. 중복된 함수들의 이름이 동일하여야 한다
2. 중복된 함수들은 매개 변수 타입이나 매개 변수의 개수가 달라야 한다
3. 함수 중복에 리턴 타입은 고려되지 않는다
좋은 점
작성이 편리하고 이름을 구분지어서 기억할 필요가 없다
int sum(int a, int b, int c){ //1
return a+b+c;
}
double sum(double a, double b){ //2
return a+b;
}
int sum(int a, int b){ //3
return a+b;
}
int main(){
cout << sum(2,5,33); //1
cout << sum(12.5,33.6); //2
cout << sum(2,6); //3
}
예제 6-1)
#include <iostream>
using namespace std;
int big(int a, int b){
if (a>b) return a;
else return b;
}
int big(int a[], int size){
int res = a[0];
for (int i=1;i<size;i++){
if (res<a[i]){
res=a[i];
}
}
return res;
}
int main(){
int array[5]={1,9,-2,8,6};
cout << big(2,3) << "\n";
cout << big(array,5) << "\n";
}
예제 6-2)
#include <iostream>
using namespace std;
int sum(int a, int b){
int result=0;
for (int i=a;i<=b;i++){
result += i;
}
return result;
}
int sum(int a){
int result = 0;
for (int i=0;i<=a;i++){
result += i;
}
return result;
}
int main(){
cout << sum(3,5) << "\n";
cout << sum(3) << "\n";
cout << sum(100) << "\n";
}
생성자 함수는 중복이 가능하다 >> 이미 그렇게 써왔음
소멸자 함수는 중복이 불가능하다
6.2 디폴트 매개 변수
매개 변수 = 디폴트 값 형태로 선언된다
디폴트 매개 변수에 디폴트 값을 전달하는 것은 컴파일러가 한다
void star(int a=5); //디폴트 값 5
디폴트 매개 변수를 가진 함수를 선언할 때, 디폴트 매개 변수는 모두 끝 쪽에 몰려 선언되어야 한다.
void calc(int a, int b=5, int c, int d=0) //error
void calc(int a,int b=5, int c=0, int d=0) //success
예제 6-4)
#include <iostream>
using namespace std;
void f(char c=' ', int line = 1);
void f(char c, int line){
for (int i=0;i<line;i++){
for (int j=0;j<10;j++){
cout << c;
}
cout << "\n";
}
}
int main(){
f();
f('%');
f('@',5);
}
디폴트 매개 변수를 가진 함수는 같은 이름의 중복 함수들과 함께 선언될 수 없다.
디폴트 매개 변수의 최대 장점은 함수 중복을 간소화 할 수 있다는 점
예제 6-5)
#include <iostream>
using namespace std;
void fillLine(int n=25, char c='*'){
for (int i=0;i<n;i++){
cout << c;
}
cout << "\n";
}
int main(){
fillLine();
fillLine(10, '%');
}
예제 6-6)
#include <iostream>
using namespace std;
class MyVector{
int *p;
int size;
public:
MyVector(int n=100){
p= new int [n];
size = n;
}
~MyVector(){
delete [] p;
}
};
int main(){
MyVector *v1, *v2;
v1 = new MyVector();
v2 = new MyVector(1024);
delete v1;
delete v2;
}
6.3 함수 중복의 모호성
함수 중복으로 인한 모호성은 3가지가 있다
1. 형 변환으로 인한 모호성
char -> int -> long -> float -> double (왼쪽에 있는 타입이 오른쪽에 있는 어떤 타입으로도 자동 형 변환 가능하다)
float square(float a);
double square(double a);
정수를 float 타입으로 형변환할지 double 타입으로 할지 모호한 경우 컴파일 오류가 발생한다
2. 참조 매개 변수로 인한 모호성
int add(int a, int b);
int add(int a, int &b);
int s=10, t=20;
add(s,t); //컴파일 오류
3. 디폴트 매개 변수로 인한 모호성
void msg(int id);
void msg(int id, string s="");
msg(6); //컴파일 오류, 둘 중 어느 것을 컴파일 해도 괜찮기 때문에
6.4 static 멤버
static은 변수와 함수 생명 주기와 사용 범위를 지정하는 방식 중 하나
생명 주기 - 프로그램이 시작할 때 생성되고 프로그램이 종료할 때 소멸
사용 범위 - 변수나 함수가 선언된 범위 내에서 사용. 전역 혹은 지역으로 구분
static 멤버는 클래스 당 하나만 생기고 모든 객체들이 공유하므로 클래스 멤버로 부를 수 있다
non-static 멤버는 각 객체마다 별도로 생성되므로 인스턴스라고 부른다
static 멤버 선언
class Person{
public:
int money; //각 person 객체의 돈을 표현
void addMoney(int money){
this->money +=money;}
static int sharedMoney; //모든 객체들이 공유하는 공금
static void addShared(int n){
sharedMoney += n;
}
};
int Person::sharedMoney = 10; //static 변수 공간 할당. 반드시 프로그램의 전역 공간에 선언
static 멤버 사용
객체 이름이나 객체 포인터를 사용하여 보통 멤버와 동일하게 다루면 된다
Person lee;
lee.sharedMoney = 500;
Person *p;
p = &lee;
p->addShared(200);
클래스명과 범위지정 연산자(::)로도 접근이 가능하다
Person::sharedMoney = 200;
Person::addShared(200);
static 멤버들은 객체가 생기기 전부터 사용이 가능
static의 활용
1. 캡슐화
class Math{
public:
static int abs(int a){ return a>0? a:-a;}
static int max(int a, int b) { return (a>b)?a:b;}
static int min(int a, int b) { return (a>b)?b:a;}
};
int main(){
cout << Math::abs(-5) << "\n";
cout << Math::max(10, 8) << "\n";
}
2. 객체 사이에 공유 변수를 만들고자 할 때
#include <iostream>
using namespace std;
class Circle{
static int num;
int radius;
public:
Circle (int r=1){
radius = r;
num++;
};
~Circle(){
num--;
}
double getArea(){
return 3.14*radius*radius;
}
static int getNum(){
return num;
}
};
int Circle::num = 0;
int main(){
Circle *p = new Circle[10];
cout << Circle::getNum() << "\n";
delete [] p;
cout << Circle::getNum() << "\n";
Circle a;
cout << Circle::getNum() << "\n";
Circle b;
cout << Circle::getNum() << "\n";
}
static 멤버 함수의 특징
1. static 멤버 함수는 오직 static 멤버들만 접근
2. static 함수는 this를 사용할 수 없다
openchallenge
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <string>
using namespace std;
class Person{
string name;
public:
void setName(string name) { this->name=name; }
string getName() { return name; }
};
class UpAndDownGame{
static int n, left, right;
public:
static void game();
};
int UpAndDownGame::n = rand()%100;
int UpAndDownGame::left = 0;
int UpAndDownGame::right = 99;
void UpAndDownGame::game(){
cout << "Up&Down 게임을 시작합니다." << "\n";
Person p[2];
p[0].setName("김인수");
p[1].setName("오은경");
int i=0;
bool solve =true;
for(; ;){
cout << "답은 " << left << "과 " << right << "사이에 있습니다." << endl;
cout << p[i % 2].getName() << ">>";
int num = 0;
cin >> num;
if (num < UpAndDownGame::n)
UpAndDownGame::left = num;
else if (num > UpAndDownGame::n)
UpAndDownGame::right=num;
else if (num == UpAndDownGame::n) {
cout << p[i % 2].getName() << "가 이겼습니다!!" << endl;
break;}
++i;
}
}
int main() {
srand((unsigned)time(0));
UpAndDownGame::game();
}
실습문제
1-1
#include <iostream>
using namespace std;
int add (int *a, int size){
int sum=0;
for (int i=0;i<size;i++){
sum += a[i];
}
return sum;
}
int add (int *a, int size, int *b){
int sum=0;
for (int i=0;i<size;i++){
sum += a[i];
sum += b[i];
}
return sum;
}
int main() {
int a[] = {1,2,3,4,5};
int b[] = {6,7,8,9,10};
int c = add(a,5);
int d = add(a,5,b);
cout << c << "\n";
cout << d << "\n";
}
1-2
#include <iostream>
using namespace std;
int add (int *a, int size, int *b=NULL){
int sum=0;
for (int i=0;i<size;i++){
sum += a[i];
}
if (b!=NULL){
for (int i=0;i<size;i++){
sum += b[i];
}
}
return sum;
}
int main() {
int a[] = {1,2,3,4,5};
int b[] = {6,7,8,9,10};
int c = add(a,5);
int d = add(a,5,b);
cout << c << "\n";
cout << d << "\n";
}
2
#include <iostream>
using namespace std;
class Person{
int id;
double weight;
string name;
public:
Person(int id=1,string name="Grace", double weight=20.5){
this->id=id;
this->name=name;
this->weight=weight;
}
void show() {
cout << id << ' ' << weight << ' ' << name << "\n";
}
};
int main() {
Person grace, ashley(2,"Ashley"), helen(3,"Helen", 32.5);
grace.show();
ashley.show();
helen.show();
}
3
1-1)
#include <iostream>
using namespace std;
int big (int a, int b){
int bigger = 0;
if (a<b){
bigger = b;}
else {
bigger = a;
}
int result = 0;
if (bigger < 100){
result = bigger;
}
else if (bigger > 100){
result = 100;
}
return result;
}
int big(int a, int b, int c){
int bigger = 0;
if (a<b){
bigger = b;}
else {
bigger = a;
}
int result = 0;
if (bigger < c){
result = bigger;
}
else if (bigger > c){
result = c;
}
return result;
}
int main() {
int x = big(3, 5);
int y = big(300, 60);
int z = big(30, 60, 50);
cout << x << ' ' << y << ' ' << z << endl;
return 0;
}
1-2)
#include <iostream>
using namespace std;
int big(int a, int b, int c=100){
int bigger = 0;
if (a<b){
bigger = b;}
else {
bigger = a;
}
int result = 0;
if (bigger < c){
result = bigger;
}
else if (bigger > c){
result = c;
}
return result;
}
int main() {
int x = big(3, 5);
int y = big(300, 60);
int z = big(30, 60, 50);
cout << x << ' ' << y << ' ' << z << endl;
return 0;
}
4
#include <iostream>
using namespace std;
class MyVector{
int *mem;
int size;
public:
MyVector(int n=100, int val=0){
mem = new int [n];
size = n;
for (int i=0;i<size;i++){
mem[i]=val;
}
}
~MyVector(){
delete [] mem;
}
void show(){
for (int i = 0; i < size; i++) {
cout << mem[i] << ' ';
}
cout << "\n";
}
};
int main() {
MyVector a, b(10, 1);
a.show();
b.show();
}
5
#include <iostream>
using namespace std;
class ArrayUtility {
public:
static void intToDouble(int source[], double dest[], int size);
static void doubleToInt(double source[], int dest[], int size);
};
void ArrayUtility::intToDouble(int source[], double dest[], int size){
for(int i=0;i<size;i++){
dest[i] = (double)source[i];
}
}
void ArrayUtility::doubleToInt(double source[], int dest[], int size){
for (int i=0;i<size;i++){
dest[i] = (int) source[i];
}
}
int main() {
int x[] = { 1,2,3,4,5 };
double y[5];
double z[] = { 9.9, 8.8, 7.7, 6.6, 5.6 };
ArrayUtility::intToDouble(x, y, 5);
for (int i = 0; i < 5; i++)cout << y[i] << ' ';
cout << "\n";
ArrayUtility::doubleToInt(z, x, 5);
for (int i = 0; i < 5; i++)cout << x[i] << ' ';
cout << "\n";
}
6
#include <iostream>
using namespace std;
class ArrayUtility2 {
public:
static int* concat(int s1[], int s2[], int size);
static int* remove(int s1[], int s2[], int size, int& retSize);
};
int* ArrayUtility2::concat(int s1[], int s2[], int size){
int* result = new int [size];
int index=0;
cout << "합친 정수 배열을 출력한다\n";
for (int i=0;i<size/2;i++){
result[index] = s1[i];
cout << result[index]<<' ';
index++;
}
for (int i=0;i<size/2;i++){
result[index] = s2[i];
cout << result[index] << ' ';
index++;
}
cout << "\n";
return result;
}
int* ArrayUtility2::remove(int s1[], int s2[], int size, int& retSize){
int cnt = 0;
int* result = new int[size];
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
if (s1[i] == s2[j]) break;
if (j == size-1)
result[cnt++] = s1[i];
}
}
retSize = cnt;
cout << "배열 x[]에서 y[]를 뺀 결과를 출력한다. 개수는 " << retSize << endl;
int* ret = new int[retSize];
for (int i = 0; i < retSize; i++) {
ret[i] = result[i];
cout << ret[i] << ' ';
}
cout << "\n";
return ret;
}
int main() {
int x[5], y[5], retSize;
int* z, *w;
cout << "정수를 5개 입력하라. 배열 x에 삽입한다>>";
for (int i = 0; i < 5; i++) {
cin >> x[i];
}
cout << "정수를 5개 입력하라. 배열 y에 삽입한다>>";
for (int i = 0; i < 5; i++) {
cin >> y[i];
}
z = ArrayUtility2::concat(x, y, 10);
w = ArrayUtility2::remove(x, y, 5, retSize);
}
7
#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std;
class Random {
public:
static void seed() { srand((unsigned)time(0)); }
static int nextInt(int min = 0, int max = 32767);
static char nextAlphabet();
static double nextDouble();
};
int Random::nextInt(int min, int max){
return rand()&(max-min)+min;
}
char Random::nextAlphabet(){
if (rand()%2==0) return rand()%26+'a';
else return rand()%26+'A';
}
double Random::nextDouble(){
return (double) rand()/RAND_MAX;
}
int main() {
cout << "1에서 100까지 랜덤한 정수 10개를 출력합니다" << endl;
for (int i = 0; i < 10; i++) {
cout << Random::nextInt(1, 100) << ' ';
}
cout << "\n";
cout << "알파벳을 랜덤하게 10개 출력합니다" << endl;
for (int i = 0; i < 10; i++) {
cout << Random::nextAlphabet() << ' ';
}
cout << "\n";
cout << "랜덤한 실수 10개를 출력합니다" << endl;
for (int i = 0; i < 10; i++) {
cout << Random::nextDouble() << ' ';
}
cout <<"\n";
}
8
#include <iostream>
#include <string>
using namespace std;
class Trace{
public:
static string log[100][20];
static int index;
static void put(string tag,string str);
static void print(string tag="");
};
string Trace::log[100][20] = { "" };
int Trace::index = 0;
void Trace::put(string tag, string str){
log[index][0] = tag;
log[index][1] = str;
index++;
}
void Trace::print(string tag){
if (!tag.empty()){
cout << "---" << tag << "태그의 Trace 정보를 출력합니다. ---\n";
for (int i=0;i<index;i++){
if (log[i][0].compare(tag)==0){
cout << log[i][0] << ":" << log[i][1] << "\n";
}
}
}
else{
cout << tag << "--- 모든 Trace 정보를 출력합니다. --- \n";
for (int i=0;i<index;i++){
cout << log[i][0] << ":" << log[i][1] << "\n";
}
}
}
void f() {
int a, b, c;
cout << "두 개의 정수를 입력하세요>>";
cin >> a >> b;
Trace::put("f()", "정수를 입력 받았음");
c = a + b;
Trace::put("f()", "합 계산");
cout << "합은 " << c << endl;
}
int main() {
Trace::put("main()", "프로그램 시작합니다");
f();
Trace::put("main()", "종료");
Trace::print("f()");
Trace::print();
return 0;
}
9
#include <iostream>
#include <string>
#include <cstring>
using namespace std;
class Board {
public:
static string *notices;
static int index;
static void add(string str);
static void print();
};
string* Board::notices = new string[100];
int Board::index = 0;
void Board::add(string str) {
notices[index++] = str;
}
void Board::print() {
cout << "******** 게시판입니다. ********" << "\n";
for (int i = 0; i < index; i++) {
cout << i << ": " << notices[i] << "\n";
}
cout << "\n";
}
int main() {
Board::add("중간고사는 감독 없는 자율 시험입니다.");
Board::add("코딩 라운지 많이 이용해 주세요.");
Board::print();
Board::add("진소린 학생이 경진대회 입상하였습니다. 축하해주세요");
Board::print();
}
'명품 C++' 카테고리의 다른 글
[명품 C++] 7. 프렌드와 연산자 중복 (0) | 2023.01.06 |
---|---|
[명품 C++] 5. 함수와 참조, 복사 생성자 (0) | 2023.01.02 |
[명품 C++] 4. 객체 포인터와 객체 배열, 객체의 동적 생성 (0) | 2022.12.30 |
[명품 C++] 3. 클래스와 객체 (0) | 2022.12.27 |
[명품 C++] 2.C++ 프로그래밍의 기본 (0) | 2022.12.26 |