함수의 중복과 static 멤버
함수 중복
•
동일한 이름의 함수가 공존한다
◦
다형성
◦
C언어에서는 불가능하다
•
function overloading
•
함수 중복이 가능한 범위
◦
보통 함수들 사이
◦
클래스의 멤버 함수들 사이
◦
상속 관계에 있는 기본 클래스와 파생 클래스의 멤버 함수들 사이
•
함수 중복 성공 조건
◦
중복된 함수들의 이름 동일
◦
중복된 함수들의 매개변수 타입이 다르거나 개수가 달라야함
◦
리턴 타입은 함수 중복과 무관
•
함수 중복 성공 사례
#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) {
if (size < 0) return 0;
int max = a[0];
for (int i = 1; i < size; i++) {
if (max < a[i]) max = a[i];
}
return max;
}
int main() {
cout << big(10, 20) << endl;
int x[] = {10,20,30,40,50,60};
cout << big(x, 6) << endl;
}
C++
복사
•
함수 중복 실패 사례
◦
리턴 타입이 다르다고 함수 중복이 성공하지 않는다
•
함수 중복의 편리함
◦
동일한 이름을 사용하면 함수 이름을 구분하여 기억할 필요없고, 함수 호출을 잘못하는 실수를 줄일 수 있음
예제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) << endl;
cout << big(array, 5) << endl;
}
C++
복사
예제2)
#include <iostream>
using namespace std;
int sum(int a, int b) {
int s = 0;
for (int i = a; i <= b; i++)
s+= i;
return s;
}
int sum(int a) {
int s = 0;
for (int i = 0; i <= a; i++)
s += i;
return s;
}
int main() {
cout << sum(3, 5) << endl;
cout << sum(3) << endl;
cout << sum(100) << endl;
}
C++
복사
생성자 함수 중복
•
생성자 함수 중복 목적
◦
객체 생성시, 매개변수를 통해 다양한 형태의 초기값 전달
string 클래스의 생성자 중복 사례
소멸자 함수 중복
•
소멸자 함수 중복 불가
◦
소멸자는 매개변수를 가지지 않음
◦
한 클래스 내에서 소멸자는 오직 하나만 존재
디폴트 매개변수
•
매개변수에 값이 넘어오지 않는 경우, 디폴트 값을 받도록 선언된 매개변수
•
‘매개변수 = 디폴트값' 형태로 선언
•
디폴트 매개변수 선언 사례
void star(int a = 5);
// a의 디폴트 값은 5
C++
복사
•
디폴트 매개변수를 가진 함수 호출
star(); // 매개변수 a에 디폴트 값 5가 전달됨, star(5); 와 동일
star(10); // 매개변수 a에 10을 넘겨줌
C++
복사
•
디폴트 매개변수 사례
•
디폴트 매개변수에 관한 제약 조건
◦
디폴트 매개변수는 보통 매개변수 앞에 선언될 수 없음
▪
디폴트 매개변수는 끝 쪽에 몰려 선언되어야 함
#include <iostream>
using namespace std;
void hello(int id=101010, string name="ASH") {
cout << "안녕 " << id << name << endl;
}
int main() {
hello(202020, "ASH");
hello(202011);
hello();
}
C++
복사
◦
매개변수에 값을 정하는 규칙
디폴트 매개변수를 가진 함수 선언 및 호출
디폴트 매개변수를 가진 함수 만들기 연습
#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 << endl;
}
}
int main() {
f();
f('%');
f('@', 5);
}
C++
복사
함수 중복 간소화
•
디폴트 매개변수의 장점 - 함수 중복 간소화
•
중복 함수들과 디폴트 매개변수를 가진 함수를 함께 사용 불가
•
중복 간소화 연습
•
중복 간소화 연습 2
public:
MyVector(int n = 100) {
p = new int[n];
size = n;
}
C++
복사
함수 중복의 모호성
•
함수 중복이 모호하여 컴파일러가 어떤 함수를 호출하는지 판단하지 못하는 경우
◦
형 변환으로 인한 모호성
◦
참조 매개변수로 인한 모호성
◦
디폴트 매개변수로 인한 모호성
1.
형 변환으로 인한 모호성
a.
매개변수의 형 변환으로 인한 중복 함수 호출의 모호성
→ 누구를 호출해야 하는지 컴파일러가 모른다
#include <iostream>
using namespace std;
void hello(int id=101010, string name="ASH") {
cout << "안녕 " << id << name << endl;
}
double square(double a) {
return a * a;
}
float square(float a) {
return a * a;
}
int main() {
hello(202020, "ASH");
hello(202011);
hello();
cout << square(10) << endl;
cout << square(1.2) << endl;
}
C++
복사
→ 형변환이 모호 (컴파일 에러)
2.
참조 매개변수로 인한 함수 중복의 모호성
3.
디폴트 매개변수로 인한 함수 중복의 모호성
static 멤버와 non-static 멤버
•
클래스의 용도는 객체를 만들기 위한 용도다
static
•
변수와 함수에 대한 기억 부류의 한 종류
◦
생명주기 - 프로그램이 시작될 때 생성, 프로그램이 종료시 소멸
◦
사용범위 - 선언된 범위, 접근 지정에 따름
클래스의 멤버
•
static 멤버
◦
프로그램이 시작할 때 생성
◦
클래스 당 하나만 생성, 클래스 멤버라고 불림
◦
클래스의 모든 인스턴스(객체)들이 공유하는 멤버
•
non-static 멤버
◦
객체가 생성될 때 함께 생성
◦
객체마다 객체 내에 생성
◦
인스턴스 멤버라고 불림
static 멤버 선언
static 멤버와 non-static 멤버 비교
static 멤버 사용 : 객체의 멤버로 접근
•
static 멤버는 객체 이름이나 객체 포인터로 접근
◦
보통 멤버처럼 접근할 수 있음
◦
Person 타입의 객체 lee 와 포인터 p 를 이용하여 static 멤버를 접근하는 예
static 멤버 사용 : 클래스명과 범위 지정 연산자(::)로 접근
◦
클래스 이름과 범위 지정 연산자(::) 로 접근 가능
▪
static 멤버는 클래스마다 오직 한 개만 생성되기 때문
▪
non-static 멤버는 클래스 이름을 접근 불가
static 활용
▪
static 의 주욜 활용
•
전역 변수나 전역 함수를 클래스에 캡슐화
◦
전역 변수나 전역 함수를 가능한 사용하지 않도록
◦
전역 변수나 전역 함수를 static 으로 선언하여 클래스 멤버로 선언
•
객체 사이에 공유변수를 만들고자 할 때
◦
static 멤버를 선언하여 모든 객체들이 공유
예제) static 멤버를 가진 Math 클래스 작성 (장점)
예제) static 멤버를 공유의 목적으로 사용하는 예
#include <iostream>
using namespace std;
class Circle {
private:
static int numOfCircles;
int radius;
public:
Circle(int r = 1);
~Circle() { numOfCircles--; } // 생성된 원의 개수 감소
double getArea() { return 3.14 * radius * radius; }
static int getNumOfCircles() { return numOfCircles; }
};
Circle::Circle(int r) {
radius = r;
numOfCircles++; // 생성된 원의 개수 증가
}
int Circle::numOfCircles = 0; // 0으로 초기화
int main() {
Circle *p = new Circle[10]; // 10개의 생성자 실행
cout << "생존하고 있는 원의 개수 = " << Circle::getNumOfCircles() << endl;
delete [] p; // 10개의 소멸자 실행
cout << "생존하고 있는 원의 개수 = " << Circle::getNumOfCircles() << endl;
Circle a; // 생성자 실행
cout << "생존하고 있는 원의 개수 = " << Circle::getNumOfCircles() << endl;
Circle b; // 생성자 실행
cout << "생존하고 있는 원의 개수 = " << Circle::getNumOfCircles() << endl;
}
C++
복사
static 멤버 함수는 static 멤버만 접근 가능
▪
static 멤버 함수가 접근할 수 있는 것
•
static 멤버 함수
•
static 멤버 변수
•
함수내의 지역변수
▪
static 멤버 함수는 non-static 멤버에 접근이 불가
•
객체가 생성되지 않은 시점에서 static 멤버 함수가 호출될 수 있기 때문
•
static 은 static 끼리만 사용
▪
non-static 멤버 함수는 static 에 접근 가능
static 멤버 함수는 this 사용불가
▪
static 멤버 함수는 객체가 생기기전부터 호출 가능
•
static 멤버 함수에서 this 사용불가
요약)
Person.h
#ifndef __PERSON_H
#define __PERSON_H
class Person {
int money;
public:
static int count;
public:
void addMoney(int money);
Person();
~Person();
int getMoney();
static int getCount();
void show();
static void addCount();
};
#endif
C++
복사
Person.cpp
#include <iostream>
#include "Person.h"
using namespace std;
int Person::count = 0;
Person::Person() {
money = 100;
count++;
}
Person::~Person() {
count--;
cout << "현재 남아있는 객체는 " << count << "개 입니다." << endl;
}
void Person::addMoney(int money) {
this->money += money;
}
int Person::getCount() {
return count;
}
int Person::getMoney() {
return money;
}
void Person::show() {
cout << money << ", " << count << endl;
}
void Person::addCount() {
count++;
int m = getCount();
cout << "m:" << m << endl;
}
C++
복사
main.cpp
#include <iostream>
#include "Person.h"
using namespace std;
void hello(int id=101010, string name="ASH") {
cout << "안녕 " << id << name << endl;
}
double square(double a) {
return a * a;
}
float square(float a) {
return a * a;
}
void msg(int id) {
cout << id << endl;
}
void msg(int id, string s="ISLAND") {
cout << id << s << endl;
}
int main() {
hello(202020, "ASH");
hello(202011);
hello();
cout << square(10.0F) << endl;
cout << square(1.2) << endl;
msg(2004, "ASH");
Person p1, p2, p3;
p1.addMoney(100);
p2.addMoney(200);
p3.addMoney(300);
p1.show();
p2.show();
p3.show();
Person *p = new Person[20];
cout << "총 생성된 객체의 수는 " << p1.count << endl;
cout << "총 생성된 객체의 수는 " << Person::count << endl;
delete [] p;
Person::addCount();
p1.addCount();
p2.addCount();
cout << "총 생성된 객체의 수는 " << Person::count << endl;
}
C++
복사
ㅇ