C++ 생성자, 디폴트 생성자, 위임 생성자
- 프로그래밍/C/C++
- 2018. 9. 13.
C++ 생성자, 디폴트 생성자, 위임 생성자
C++에서 생성자에 대해서 알아보겠다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | #include <iostream> using namespace std; class Position { public: int x; int y; char ch; void OutPosition() { cout << x << " " << y << " " << ch << endl; } }; int main() { Position Here; Here.x = 5; Here.y = 10; Here.ch = 'A'; Here.OutPosition(); return 0; } | cs |
class Position 선언이 되어있다.
20~22행은 각 멤버 변수를 초기화 시켜주고 있다.
만약 위와 같이 이렇게 초기화를 시켜주는데 멤버 변수가 10개라면??
이렇게 일일이 타이핑을 쳐가면서 초기화를 시켜줄 것인가??
그래서 클래스에서 지원하는 생성자를 활용해보자.
Position형의 Here를 선언했다면 디폴트 생성자라고 컴파일러가 자동으로 넣어주게 된다.
생성자는 리턴타입이 없고 이름이 클래스와 같으며, 오버로딩이 가능하다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | #include <iostream> using namespace std; class Position { public: int x; int y; char ch; Position() { } Position(int x, int y, char ch) { this->x = x; this->y = y; this->ch = ch; } void OutPosition() { cout << x << " " << y << " " << ch << endl; } }; int main() { Position Here(5,10,'A'); Here.OutPosition(); return 0; } | cs |
10행을 보면 디폴트 생성자라고 컴파일러가 만들어주는 생성자이다.
우리는 이것을 명시를 해줘도 되고 안해줘도 된다.
11행은 우리가 만들어주는 생성자인다.
생성자는 주로 멤버 변수를 초기화 해주는데 사용이 된다.
24행에서 Here 객체를 생성하게 되면 자동으로 11행에 있는 생성자가 실행이 된다.
만약 24행을 Position Here; 로 객체를 만들어주게 되면 10행 생성자가 실행이 된다.
이때 11행을 멤버 초기화 리스트라는 것을 해보자.
12~14행을 지우고
Position(int x, int y, char ch) : x(x), y(y), ch(ch) {}
이렇게 해도 된다.
이때 괄호 밖에 있는 것은 무조건 클래스 멤버 변수가 되고 안에 있는 것은 매개 변수가 된다.
만약 Here를 배열로 만들려면 어떻게 해야 될까??
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | #include <iostream> using namespace std; class Position { public: int x; int y; char ch; Position() { } Position(int x, int y, char ch) : x(x), y(y), ch(ch) {} void OutPosition() { cout << x << " " << y << " " << ch << endl; } }; int main() { Position Here[3] = { Position(1,2,'x'), Position(3,4,'y'), Position(5,6,'z') }; Here[0].OutPosition(); return 0; } | cs |
20행 처럼 해주면 된다.
생성자를 일일이 호출하여서 배열을 만들면 된다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | #include <iostream> using namespace std; class Position { public: int x; int y; char ch; Position() { } Position(int x, int y, char ch = 'A') : x(x), y(y), ch(ch) {} void OutPosition() { cout << x << " " << y << " " << ch << endl; } }; int main() { Position Here(1, 2); Here.OutPosition(); return 0; } | cs |
11행에서 char ch = 'A' 라고 디폴트 매개변수를 넣어주고
20행에서 인자를 두개만 넣어줘도 가능하다.
그리고
Position Here { 1, 2, 'A'}; 이렇게 하면 생성자 없이 멤버 변수 초기화가 가능하다.
단, 멤버 변수가 public 일때만 가능하다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | #include <iostream> using namespace std; class A { public : A() { cout << "A 생성자" << endl; } }; class B { A a; public : B() { cout << "B 생성자" << endl; } }; int main() { B b; return 0; } | cs |
class B가 A 클래스를 멤버변수로 포함하고 있다면 어떻게 될까??
23행에서 B 객체를 만들어주고 있다.
그럼 클래스가 객체화 될 때 먼저 멤버 변수를 메모리 공간에 할당을 시켜준다.
그러므로 class A로 이동해서 A 생성자가 호출된다.
그리고 B 생성자가 호출된다.
즉, 클래스 선언을 할 때 멤버 변수가 먼저 생성이 된다는 것을 알 수 있다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | #include <iostream> using namespace std; class A { int a; public : A(int a) : a(a){ cout << "A 생성자" << " " << a << endl; } }; class B { int m_a; A c_a; public : B(int m_a) : m_a(m_a), c_a(m_a) { cout << "B 생성자" << m_a << endl; } }; int main() { B b(10); return 0; } | cs |
B 객체를 생성할 때 10을 인자로 주고
생성자에서 A의 클래스 멤버변수 a를 초기화를 이렇게 시켜주어도 가능하다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | #include <iostream> #include <string> using namespace std; class Student { int id; string name; public : Student(const string &name_in) : Student(0, name_in) {} Student(const int &id_in, const string &name_in) : id(id_in), name(name_in) {} }; int main() { Student st1(1, "aossuper7"); Student st2("aossuper7"); } | cs |
이렇게 17행에서 문자열만 초기화 할때 다른 생성자를 불러서 초기화도 가능하다.
이런것을 위임 생성자라고 한다.