C++ Chapter 8.3 : 생성자

Date:     Updated:

카테고리:

태그:

인프런에 있는 홍정모 교수님의 홍정모의 따라 하며 배우는 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)
        • 인수로 각 멤버를 초기화 해준다.

매개 변수에 기본 값 설정 하면

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 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로 형변환해준다.



🌜 개인 공부 기록용 블로그입니다. 오류나 틀린 부분이 있을 경우 
언제든지 댓글 혹은 메일로 지적해주시면 감사하겠습니다! 😄

맨 위로 이동하기


Cpp 카테고리 내 다른 글 보러가기

댓글 남기기