Search
Duplicate

6장. 함수의 중복과 static 멤버

생성일
2022/04/10 06:07
태그
C++

함수의 중복과 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++
복사