Computer Science/C++

[C++] 클래스 / 함수의 오버로딩, 생성자 - 씹어먹는 C++

토마토. 2021. 7. 21. 15:09

<다루는 내용>

함수의 오버로딩

function overloading

생성자

constructor

디폴트 생성자

default constructor

 

 

<함수의 오버로딩>

 

C++에서는 같은 이름을 가진 함수가 여러개 존재해도 된다.

함수를 호출할 때 사용하는 인자를 보고,

함수들을 구분하게 된다.

 

#include <iostream>


void print(int x) {
  std::cout << "int : " << x << std::endl;
}

void print(char x) {
  std::cout << "char : " << x << std::endl;
}

void print(double x) {
  std::cout << "double : " << x << std::endl;
}

int main() {
  int a = 1;
  char b = 'c';
  double c = 3.2f;

  print(a);
  print(b);
  print(c);

  return 0;
  
}

 

만약에 자신과 정확히 일치하는 인자를 가지는 함수가 없으면

자신과 최대한 근접한 함수를 찾게 된다.

#include <iostream>


void print(int x) {
  std::cout << "int : " << x << std::endl;
}

void print(double x) {
  std::cout << "double : " << x << std::endl;
}

int main() {
  int a = 1;
  char b = 'c';
  double c = 3.2f;

  print(a);
  print(b);
  print(c);

  return 0;

}

 

ex)

char, unsigned char, short -> int

float -> double

enum -> int

 

*오버로딩 규칙 숙지 중요함*

 

-> 함수의 오버로딩 과정 <-

 

1.

타입 A -> 타입 A

2. 

정확히 일치하지 않는 경우형변환 실시함char, unsigned char, short -> intunsigned short -> unsigned int/intfloat -> doubleenum -> int

3.

float -> intenum -> double0 -> pointer type, numberic type*ptr -> void*

 

<Date Class>

#include <iostream>

class Date {
  int year_;
  int month_;  // 1 부터 12 까지.
  int day_;    // 1 부터 31 까지.

 public:
  void SetDate(int year, int month, int date);
  void AddDay(int inc);
  void AddMonth(int inc);
  void AddYear(int inc);

  // 해당 월의 총 일 수를 구한다.
  int GetCurrentMonthTotalDays(int year, int month);

  void ShowDate();
};

void Date::SetDate(int year, int month, int day) {
  year_ = year;
  month_ = month;
  day_ = day;
}

int Date::GetCurrentMonthTotalDays(int year, int month) {
  static int month_day[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
  if (month != 2) {
    return month_day[month - 1];
  } else if (year % 4 == 0 && year % 100 != 0) {
    return 29;  // 윤년
  } else {
    return 28;
  }
}

void Date::AddDay(int inc) {
  while (true) {
    // 현재 달의 총 일 수
    int current_month_total_days = GetCurrentMonthTotalDays(year_, month_);

    // 같은 달 안에 들어온다면;
    if (day_ + inc <= current_month_total_days) {
      day_ += inc;
      return;
    } else {
      // 다음달로 넘어가야 한다.
      inc -= (current_month_total_days - day_ + 1);
      day_ = 1;
      AddMonth(1);
    }
  }
}

void Date::AddMonth(int inc) {
  AddYear((inc + month_ - 1) / 12);
  month_ = month_ + inc % 12;
  month_ = (month_ == 12 ? 12 : month_ % 12);
}

void Date::AddYear(int inc) { year_ += inc; }

void Date::ShowDate() {
  std::cout << "오늘은 " << year_ << " 년 " << month_ << " 월 " << day_
            << " 일 입니다 " << std::endl;
}

int main() {
  Date day;
  day.SetDate(2011, 3, 1);
  day.ShowDate();

  day.AddDay(30);
  day.ShowDate();

  day.AddDay(2000);
  day.ShowDate();

  day.SetDate(2012, 1, 31);  // 윤년
  day.AddDay(29);
  day.ShowDate();

  day.SetDate(2012, 8, 4);
  day.AddDay(2500);
  day.ShowDate();
  return 0;
}

 

<생성자 constructor>

 

생성자는

객체 생성시에 자동으로 호출해주는 함수라고

할 수 있다.

 

(생성 후 초기화를 도와주는 장치)

 

date(int year, int month, int day) {}

와 같은 형식으로 생성자를 정의한다.

 

Date(int year, int month, int day)라고 정의했다면

Date day(2011, 3, 1);은

day 객체를 만들어 생성자 Date를 호출한다는 뜻이 된다. 

 

 

<디폴트 생성자 default constructor>

 

Date day;

와 같이 생성자 정의를 하지 않은 채

생성자를 호출하면? 

디폴트 생성자 Default Constructor가 호출된다. 

 

디폴트 생성자 정의하는 법

Date() {year = 2012;month = 7;day = 12;}

 

#include <iostream>

class Date {
  int year_;
  int month_;
  int day_;
  
  public:
    void ShowDate();

    Date(){
      year_=2012;
      month_ = 7;
      day_= 12;
    }
};

void Date::ShowDate(){
  std::cout<<year_<<"년 " <<month_<<"월 " <<day_<<"일 "<<std::endl;
}

int main(){
  Date day = Date();
  Date day2;

  day.ShowDate();
  day2.ShowDate();

  return 0;  
}

 

<생성자 오버로딩>

#include <iostream>


class Point {
  int x, y;

 public:
  Point(int pos_x, int pos_y);
};

class Geometry {
 public:
  Geometry() {
    num_points = 0;
  }

  void AddPoint(const Point &point) {
    point_array[num_points ++] = new Point(point.x, point.y);
  }

  // 모든 점들 간의 거리를 출력하는 함수 입니다.
  void PrintDistance();

  // 모든 점들을 잇는 직선들 간의 교점의 수를 출력해주는 함수 입니다.
  // 참고적으로 임의의 두 점을 잇는 직선의 방정식을 f(x,y) = ax+by+c = 0
  // 이라고 할 때 임의의 다른 두 점 (x1, y1) 과 (x2, y2) 가 f(x,y)=0 을 기준으로
  // 서로 다른 부분에 있을 조건은 f(x1, y1) * f(x2, y2) <= 0 이면 됩니다.
  void PrintNumMeets();

private:
  // 점 100 개를 보관하는 배열.
  Point* point_array[100];
  int num_points;
};

<생각해보기 :D>