C++ Chapter 8.3 : 생성자
카테고리: Cpp
태그: Cpp Programming
인프런에 있는 홍정모 교수님의 홍정모의 따라 하며 배우는 C++ 강의를 듣고 정리한 필기입니다. 😀
🌜 [홍정모의 따라 하며 배우는 C++]강의 들으러 가기!
chapter 8. 객체 지향의 기초 : 생성자
🔔 생성자란?
생성자 : 객체가 메모리에 잡히자마자 실행되는 함수. 즉 객체가 생성되자마자 실행되는 함수다.
- 객체가 생성되자마자 호출되기 때문에 주로 멤버들을 초기화하 하는 내용이 들어간다.
- 꼭 멤버들을 초기화하는 내용이 아니더라도 객체가 생성되자마자 실행되야 할 함수라던가 그런게 있으면 생성자에 넣어주면 된다!
- 이름이 클래스의 이름과 같다.
- 객체가 생성되자마자 실행되야 하므로
public
이어야 한다.
#include <iostream>
using namespace std;
class Fraction
{
private: // 캡슐화
int m_numerator; // 분자
int m_denominator; // 분모
public:
Fraction() // ✨생성자✨
{
m_numerator = 0;
m_denominator = 1;
}
void print()
{
cout << m_numerator << " / " << m_denominator << endl;
}
};
int main()
{
Fraction frac; // 객체가 생성되면서 생성자가 호출된다.
frac.print(); // "0 / 1" 출력
return 0;
}
- Fraction frac;
- 객체가 생성되면서 생성자가 호출된다.
- m_numerator = 0 으로 초기화 됨
- m_denominator = 1 으로 초기화 됨
🔔 생성자의 매개변수
#include <iostream>
using namespace std;
class Fraction
{
private:
int m_numerator;
int m_denominator;
public:
Fraction(const int & num_in, const int & den_in) // ✨생성자✨
{
m_numerator = num_in;
m_denominator = den_in;
cout << "Fraction() constructors, frac" << endl;
}
void print()
{
cout << m_numerator << " / " << m_denominator << endl;
}
};
int main()
{
Fraction one_thirds(1, 3); // 객체가 생성되면서 생성자가 호출된다.
one_thirds.print(); // "1 / 3" 출력
return 0;
}
- Fraction one_thirds(1, 3);
- Fraction 타입의 one_thirds 객체 생성
- 생성자에 인수 2개를 넘겨준다.
- 매개변수 2개 가진 생성자 호출
- Fraction(const int & num_in, const int & den_in)
- 인수로 각 멤버를 초기화 해준다.
- 매개변수 2개 가진 생성자 호출
매개 변수에 기본 값 설정 하면
7.6 매개변수 기본 값 설정 해당 포스트 내용처럼 생성자 또한 매개 변수에 기본 값을 설정할 수 있다.
#include <iostream>
using namespace std;
class Fraction
{
private:
int m_numerator;
int m_denominator;
public:
Fraction(const int & num_in, const int & den_in = 5) // ✨생성자✨
{
m_numerator = num_in;
m_denominator = den_in;
cout << "Fraction() constructors, frac" << endl;
}
void print()
{
cout << m_numerator << " / " << m_denominator << endl;
}
};
int main()
{
Fraction one_thirds(2); // 이렇게 인수 1개만 넘겨도 매개변수 다른 하나는 디폴트 값이 있으므로 괜찮다.
one_thirds.print(); // "2 / 5" 출력
return 0;
}
- Fraction(const int & num_in, const int & den_in
= 5
)- Fraction frc(3); 객체 생성시 이렇게 매개변수 1개의 생성자를 호출해도, 매개변수 num_in에는 3이, 매개변수 den_in 에는 기본 값인 5가 들어오게 된다.
- 단, 매개 변수 1 개짜리 생성자가 없을 때라는 전제 하에!
- 매개 변수 1개짜리 생성자 또한 있을 때 Fraction frc(3);를 호출하면 매개 변수 1개짜리 생성자를 호출해야 하는지, 매개 변수 하나는 기본 값이 설정 되어 있는 매개변수 2개짜리 생성자를 호출해야 하는지 애매 모호 하기 때문에 에러가 난다.
- Fraction frc(3); 객체 생성시 이렇게 매개변수 1개의 생성자를 호출해도, 매개변수 num_in에는 3이, 매개변수 den_in 에는 기본 값인 5가 들어오게 된다.
첫 번째 주의 사항
매개변수가 없는 생성자를 호출할 땐 반드시 ()
을 빼야 한다. Fraction f();
로 호출하는 것이 아니라 Fraction f;
로 호출해야 한다. ()
괄호는 매개변수 있는 생성자를 호출할 때만.
Fraction f; // 매개 변수 없는 생성자 호출
Fraction f(); // 에러!✨ C++에선 없는 표현이다.
두 번째 주의 사항
클래스 안에 생성자 정의가 아예 없을 때
사실 아무 일도 안하는 Fraction() {}
매개변수 없는 기본 생성자가 숨어 있다. 그래서 Fraction 클래스가 생성자가 없다 하더라도 Fraction frac;
객체를 생성하면 숨어있던 기본 생성자가 호출된다
클래스 안에 매개변수 있는 생성자 정의가 하나라도 있을 땐 매개변수 없는 기본 생성자를 호출할 수 없다.
#include <iostream>
using namespace std;
class Fraction
{
private:
int m_numerator;
int m_denominator;
public:
Fraction(const int & num_in, const int & den_in = 5) // ✨생성자✨
{
m_numerator = num_in;
m_denominator = den_in;
cout << "Fraction() constructors, frac" << endl;
}
void print()
{
cout << m_numerator << " / " << m_denominator << endl;
}
};
int main()
{
Fraction frac; // 에러 ⭐⭐⭐
return 0;
}
- 생성자 정의가 아예 없을 땐 아무 일도 하지 않는 기본 생성자를 만들어주어 호출이 가능했지만
- 매개 변수를 가지고 있는 생성자가 하나라도 있을 땐 매개변수가 없는 생성자는 없으므로 기본 생성자는 호출이 불가능해진다.
#include <iostream>
using namespace std;
class Fraction
{
private:
int m_numerator;
int m_denominator;
public:
Fraction() // 기본 생성자
{}
Fraction(const int & num_in, const int & den_in = 5) // 매개변수 1개 생성자✨
{
m_numerator = num_in;
m_denominator = den_in;
cout << "Fraction() constructors, frac" << endl;
}
void print()
{
cout << m_numerator << " / " << m_denominator << endl;
}
};
int main()
{
Fraction frac; // 기본 생성자 호출
return 0;
}
- 기본 생성자 또한 정의해주니 이제는
Fraction frac;
에서 에러가 나지 않는다.
🔔 생성자 호출시 ()와 {}의 차이
Fraction frac{1, 3};
Fraction frac(1, 3);
{}
을 사용하여 호출하는게 더 엄격하다. 자동으로 형변환 해주지 않음!
Fraction frac{1.0, 3.0}; // 에러 O
Fraction frac(1.0, 3.0); // 에러 X
Fraction 생성자에서 인수를 int 로 받는다고 가정해보자. 인수를 double 타입으로 넘길 시, {}
로 호출할 땐 자동 형변환을 해주지 않으므로 에러가 나지만 ()
로 호출할 땐 자동 형변환을 해주기 때문에 에러가 나지 않고 인수를 int로 형변환해준다.
🌜 개인 공부 기록용 블로그입니다. 오류나 틀린 부분이 있을 경우
언제든지 댓글 혹은 메일로 지적해주시면 감사하겠습니다! 😄
댓글 남기기