함수 중복은 같은 이름으로 함수를 여러개 만드는 것을 의미한다.
중복된 함수를 만들기 위해서는 다음의 조건이 모두 만족되야 한다.
사용 예시)
int sum(int a, int b, int c){
return a+b+c;}
double sum(int a, int b){ // 매개 변수의 개수가 다르다.
return a+b;}
int sum(double a, double b){ //매개변수의 타입이 다르다.
return a+b;}
이처럼 같은 이름으로 매개변수의 개수나 타입이 다른 매개변수를 가진 "같은 이름"의 함수를 정의하면 함수 호출시 입력값(매개변수)에 따라 자동으로 분류되어 함수를 사용하게 된다.
int sum(int a, int b){
return a+b;}
int sum(int a, int b){
return (double)a+b;}
int main(){
sum(1,2);
}
위 코드에서 sum호출시 컴파일러는 위 두 함수중 어떤 함수를 호출해야하는지 알 수 없으므로 Error를 출력한다.
일반 함수 뿐 아니라 생성자도 중복이 가능하다. 다만, 소멸자는 근본적으로 매개 변수를 가지지 않고, 객체를 닫는다는 의미 때문에 절대 중복이 불가능하다.
매개변수를 지정할 때 변수에 값이 넘어오지 않는다면, defalt값을 자동으로 넣어줄 수 있는 기능이다.
void star(int a=5);//defalt값 지정
int main(){
star();
star()호출시, 매개변수 a에 5가 자동으로 저장된다.
단, 디폴트 매개변수와, 일반 매개변수가 같이 있을 때, 디폴트 매개변수는 일반변수를 모두 정의한 후 뒤쪽에 정의한다.
void sum(int id, int pass = 1); O
void sum(int pass = 1, int id); X
Circle(){radius=1};
Circle(int r) {radius = r};
위 같은 코드를 아래와 같이 1개로 통일 가능
Circle(int r=1) {radius = r};
void sum(int a, int b=1, int c=1);
sum() X
sum(1) O
sum(1,2) O
sum(1,2,3) O
함수 중복 조건을 갖추어도 함수 중복의 모호성으로 인해 오류를 발생시킬 수도있다.
자바에는 자동 형변환이라는 기능이 존재하며, 함수호출을 통해 매개변수를 받을 시
다음과 같이 작은 타입에서 큰 타입으로 자동 변환해 입력한다.
char -> int -> long -> float -> double
만약에 아래와 같이 3(int)로 함수를 호출했는데, 함수의 매개변수를 double로 지정했다면,
자동으로 3의 타입이 int에서 double로 변환된다.
double square(double a); // double로 매개변수를 형변환해 받는다.
int main(){
square(3);// int로 입력했지만,
}
만약 같은 확장이 가능하면서도, 실수타입인 float, double 형을 동시에 지정하면 어떻게 될까?
double square(double a); // double로 변환?
float square(float a); // float로 변환? - 컴파일러가 햇갈려 한다.
int main(){
square(3);// int로 입력했지만,
}
컴파일 과정에서 에러를 출력한다.
중복된 함수 중에서 참조 매개변수를 가진 함수가 존재하면, 에러가 발생한다.
int add(int a, int b); // 값만 복사하는 경우
int add(int a, int &b); // 주소값을 복사하는 경우
int s=10, t=20;
add(s,t);
이 때 b의 주소를 불러오는 것인지? 값을 불러오는것인지 컴파일과정에서 모호함이 발생해 에러를 출력한다.
void msg(int id)
void msg(int id, string s="한국");
msg(6);
""처럼 디폴트 매개변수를 지정할 경우, 디폴트 매개변수를 호출 할지, 매개변수가 1개인 msg를 호출할지 햇갈려하기 때문에 컴파일 에러가 난다.
static이란? 같은클래스에서 나온 객체의 맴버(변수,함수)를 다른명의 객체 끼리 공유하는 기능이다. static이 지정되면, 그 함수, 변수는 프로그램이 시작할 때 생성되며, 프로그램이 종료될 때 삭제된다. (==메모리의 DATA영역에 함수와 변수를 저장한다.:)
이때 non-static 맴버변수, 함수는 각 객체마다 별도로 생성된다는 의미에서 "인스턴스"라고 부르며, static 맴버변수, 함수는 클래스당 하나만 생기며, 모든 객체들이 공유한다는 의미에서 클래스 함수 라고도 부른다.
반드시 전역공간에 맴버변수를 구현해야 한다. 그렇지 않으면 링크과정에서 오류가 발생한다.
1. 클래스 내부
static int sharedMoney; //전역 변수 생성
static void addShared(int n){ //전역함수 생성
sharedMoney += n;
}
2. 전역함수는 구현부를 전역변수에 반드시 할당해야한다.
int BANK::addShared(int n){
int sharedMoney = 10;
}
변수명 접근
Person lee; //객체 lee로 생성
lee.sharedMoney = 500;
포인터 접근
Person *p;
p = &lee;
p-> addShared(200);
static 맴버는 클래스당 1개만 존재할 수 있음으로, 객체가 아닌 클래스 명으로도 접근이 가능하다.
Person::sharedMoney = 200;
Person::addShared(200);
non-static맴버는 당연히, 클래스명이 아닌 객체명이나 포인터로만 접근 가능하다.
객체가 생성되기 전(프로그램 시작시)에도 호출이 가능하다.
따라서 static멤버 함수에서 non-static 멤버를 호출할 수 없다.
반대로 non-static멤버에서 static멤버는 자유로이 접근할 수 있다.
this를 통한 접근이 불가능하다.(this자체가 특정 객체를 가르킬때 사용하기 때문이다.)