만약 모든 member가 public이라면 우리는 list-initialization으로도 클래스를 초기화 할 수 있다
class Foo
{
public:
int m_x {};
int m_y {};
};
int main()
{
Foo foo { 6, 7 }; // list-initialization
return 0;
}
하지만 member variable이 private한 경우에는 저렇게 외부에서 접근이 불가능하다
그렇다면 우리는 어떻게 초기화해야 할까?
constructor는 special member function이다
class object가 생성되면서 호출되는
다른 멤버 function과 달리 constructor는 정확한 naming rule이 존재한다
1. Constructors must have the same name as the class (with the same capitalization)
2. Constructors have no return type (not even void)
parameter가 없는 constructor를 default constructor라고 한다
parameter를 이용해 initialization도 가능하다
#include <cassert>
class Fraction
{
private:
int m_numerator {};
int m_denominator {};
public:
Fraction() // default constructor
{
m_numerator = 0;
m_denominator = 1;
}
// Constructor with two parameters, one parameter having a default value
Fraction(int numerator, int denominator=1)
{
assert(denominator != 0);
m_numerator = numerator;
m_denominator = denominator;
}
int getNumerator() { return m_numerator; }
int getDenominator() { return m_denominator; }
double getValue() { return static_cast<double>(m_numerator) / m_denominator; }
};
위의 constructor를 보면 default constructor와
parameter가 존재하는 constructor도 있다
Fraction fiveThirds{ 5, 3 }; // List initialization, calls Fraction(int, int)
Fraction threeQuarters(3, 4); // Direct initialization, also calls Fraction(int, int)
위와 같이 부를 수도 있고
Fraction six{ 6 }; // calls Fraction(int, int) constructor, second parameter uses default value of 1
default parameter를 하나 쓰므로 위와 같이도 constructor를 호출할 수 있다
parameter defalut value로 redundant한 default constructor를 생략할 수도 있다
#include <cassert>
class Fraction
{
private:
int m_numerator {};
int m_denominator {};
public:
// Default constructor
Fraction(int numerator=0, int denominator=1)
{
assert(denominator != 0);
m_numerator = numerator;
m_denominator = denominator;
}
int getNumerator() { return m_numerator; }
int getDenominator() { return m_denominator; }
double getValue() { return static_cast<double>(m_numerator) / m_denominator; }
};
만약 너가 정의한 class가 constructor가 존재하지 않다면
c++은 자동적으로 default constructor를 정의해준다
이를 implicit constructor라고 부른다
만약 class가 다른 class를 member로 가지고 있을 때
어떤 class constructor가 먼저 호출될까?
#include <iostream>
class A
{
public:
A() { std::cout << "A\n"; }
};
class B
{
private:
A m_a; // B contains A as a member variable
public:
B() { std::cout << "B\n"; }
};
int main()
{
B b;
return 0;
}
위와 같은 코드에 b가 default constructor로 instantiate된다면
출력은 다음과 같다
A
B
생각해보면 위의 결과가 합리적이다. 만약 B의 constructor가 A멤버를 사용할 수도 있으므로
B의 constructor가 호출되기 이전에 A가 생성되어 있어야 한다는 것이다
constructor는 object를 create하는 것이 아니다
object가 만들어질 때 initialize에 도움을 주는 것이라고 이해하자
constructor의 목적은