오늘 강의의 전체 흐름
생성자 리스트 설명하기 위해 ( 객체, 생성자, 소멸자, 멤버 변수 초기화 ) 개념 잡고 접근
포인터형과 참조형 설명하기 위해 ( 함수와 변수, 데이터 타입 ) 개념 잡고 접근
객체
- - It 쪽에서 말하는 객체와 게임 쪽에서 말하는 객체의 정의가 다르다.
- 대상 객체가 될 수 있는 공통 조건 -> 데이터화를 시킬 수 있어야 한다는 점
- IT 쪽에서는 - 현실 세계에 있는 명사나 대명사로 표현 가능한 모든 것
- 게임 쪽에서는 - 용, 귀신, 악마 등 상상할 수 있는 모든 것
생성자
- 객체를 생성하는 경우 생성자가 반드시 필요하다.
- 그런데 우리가 생성자를 안 만들어도 객체가 만들어지는 이유는?
- 생성자를 따로 만들지 않는 경우 컴파일러가 자동으로 기본 생성자 코드를 삽입해준다.
- 다만, 인자를 받는 생성자나 // 디폴트 생성자를 우리가 만들어 놓은 경우 - 컴파일러는 기본 생성자 안 만들어준다.
- Student(){ } - 생성자 - 선행됨
- ~Student(){ } - 소멸자 - 후행됨
- 객체 생성 시에 자동으로 디폴트 생성자가 호출되는 것이다~ -컴파일러가 자동으로 해줌
- 객체 삭제 시에 자동으로 디폴트 소멸자가 호출되는 것이다~ -컴파일러가 자동으로 해줌
멤버 변수의 값을 초기화시켜줄 때 생성자와 소멸자 주로 사용
디폴트 생성자 만들어 줄 경우에는 멤버 변수들 다 초기화해주는 방식으로 만들기!
출력된 것에서 차이 점 check!
소멸자
- 객체가 없어질 때 컴파일러에 의해 자동으로 호출된다. ~Student(){ } 형식으로 만들어 준다.
생성자 초기화 리스트 - C++에만 있는 기능
지금까지 생성자를 만드는 데 사용한 방법은
이미 메모리 할당이 다 끝난 상태에서 대입 연산으로 값을 넣어 주는 방식이었다.
- Student( ) { _age =0; _address="주소 없음"; _grade=0; _classNum=0; }
C++에서는 메모리 할당과 동시에 값을 입력하는 방법을 사용할 수 있다.
- Student( ) : _age(age), _address(address), _grade(0), _classNum(0) { }
함수와 변수
함수와 변수는 선언하는 위치에 따라 변수의 성격이 달라진다.
함수
- 멤버 함수 – 클래스 내부의 함수 - 객체를 통해서만 호출할 수 있다.
- 일반 함수 – 클래스 외부의 함수 - 바로 직접 호출할 수 있다.
변수
- 멤버 변수 - 클래스 내부에 만들어진 변수
- 외부 변수 – ( = 전역 변수 ) - 함수의 바깥쪽에 만들어진 변수
- 지역변수 – ( = 자동 변수 ) - 함수 내부 { } 블록 안에서만 호출이 가능한 변수 - { } 블록 끝나면 사라짐
- static 정적 변수 – ( = 로컬 변수 ) - 블록 끝나도 없어지지 않음 – 프로그램 종료 시까지 안 없어짐.
포인터형 변수 ref& , 참조형 변수 int* pa / *pa
포인터형
변수가 만들어질 때
정수형을 저장할 int, 문자열을 저장할 string, 실수를 저장할 float처럼 dataType 이 필요한데
주소 값( & )을 저장하는 dataType 은?
그것이 바로 포인터형 ( * )이라고 한다.!
포인터형에는 ( * )의 쓰임새에 따라 1. 포인터 형 지정자 2. 포인터 연산자로 나뉜다.
1. 포인터 형 지정자
- a의 주소 값을 나타낼 때는 &a라고 한다. -> &a를 저장할 수 있는 dataType은 * 포인터 형 지정자
- a가 int 값을 저장하는 변수이므로 int* pa = &a; -> int 형 변수를 저장하고 있는 공간의 주소 값!
- int* 에서 ( * )는 #포인터 형 지정자
2. 포인터 연산자
- 주소를 저장하는 변수를 만들 때는 int* pa = &a;
- a의 주소 값을 나타내는 &a에다가 포인터 연산자(*)를 쓰면 -> *&a -> 공간을 의미!
- *pa라고 하면 -> pa = &a 저장되어있다. -> *&a와 같은 것이다. -> a의 주소 값을 저장하고 있는 공간 -> a
- 따라서 *pa = a가 되는 것으로, *pa를 통해 a의 값을 변경할 수 있다.
- *pa = a에서 ( * )는 #포인터 연산자
다음 수업에서 한 번 더 설명하면서 다룰 예정! 그때 한 번 더 체크!
참조형
포인터형과 내부적으로 적용되는 코드는 똑같다.
차이점은
1. 정의와 동시에 초기화가 필요하다는 점
2. 포인터형처럼 pa나 ppa 변수를 생성 - 메모리가 따로 생긴다 - 참조형 &ref는 변수를 따로 생성하는 것이 아닌 X
- 들어온 주소 값의 공간만 참조한다.
3. 포인터형은 pa나 *pa의 값을 변경할 수 있지만, 참조형 ( & ) 은 처음 들어온 주소 값의 공간만 참조 - 변경 불가능
선언 방법 int &refa = b; -> 항상 b의 주소 값 공간을 가리키는 것이고, 변경 불가능하다.
메모리가 따로 생성되는 변수가 아니라, b에 접근할 수 있는 별칭이 하나 더 생긴 것이라고 이해
review
이번 강의의 메인 포인트는
생성자 초기화 리스트, 포인터형 지정자와 포인터 연산자, 참조형이었다.
C++에만 있는 생성자 초기화 리스트와 포인터형은 주소 값을 저장할 수 있는
데이터 타입 - 포인터 형 지정자가 있기에 가능!
생성자 초기화 리스트 ----
대입 연산으로 값 대입 X 아닌 메모리 할당과 동시에 초기화시켜주는 방법!
Student( ) : _age(age), _address(adress) { } 형식으로 사용
포인터형 지정자 ---- int* pa = &a
포인터형 연산자 ---- *pa = 1000;
참조형 ---- int& refa = a
C++에만 있는 생성자 초기화 리스트와 포인터형
이 외에도 객체의 정의 관점이 다를 수 있다는 것
객체 없어질 때 소멸자가 자동으로 불려지고 있었다는 것
변수나 함수를 사용하면 외부적으로 이렇게 작동되는구나 했던 부분들을
내부적으로 메모리가 어디에 어떻게 할당되고, 불려 오고 하는 것을 알 수 있어서 좋았다.
생성자 초기화리스트 실습해본 코드
#include <iostream>
#include <string>
using namespace std;
class Student {
private:
int _age;
string _address;
int _grade;
int _classNum;
string _name;
public:
Student() : _age(0), _address("주소없음"), _grade(0), _classNum(0), _name("이름없음")
{
cout << "기본 생성자" << endl;
cout << endl;
}
Student(string name, int age, string address)
: _name(name), _age(age), _address(address), _grade(0), _classNum(0)
{
cout << _name << "이 인자 2개를 받는 생성자" << endl;
cout << endl;
}
Student(string name, int age, string address, int grade, int classNum)
:_name(name), _age(age), _address(address), _grade(grade), _classNum(classNum)
{
cout << _name << "이 인자 4개를 받는 생성자" << endl;
cout << endl;
}
//소멸자
~Student() {
cout << _name << "의 소멸자 " << endl;
cout << endl;
}
void SetAge(int value) {
_age = value;
}
int GetAge() {
return _age;
}
void Info() {
cout << "이름: " << _name << endl;
cout << "나이: " << _age << endl;
cout << "주소: " << _address << endl;
cout << "학년: " << _grade << endl;
cout << "반: " << _classNum << endl << endl;
}
};
int main() {
Student a("오학생", 10, "런던");
Student b;
a.Info();
b.Info();
return 0;
}
포인터형과 참조형 실습해본 코드
#include <iostream>
using namespace std;
int global = 10; //외부 변수
class A {
public:
int _value; // 멤버변수
void func() {//멤버함수
int a = 0; // 지역변수
global = 100;
}
};
void func() { // 일반함수
static int score = 0; // 정적변수, 로컬변수
global = 10;
}
int main() {
//a의 주소값을 저장하는 공간생기는 포인터변수 int* pa
//*pa 는 현재 a의 주소값을 가리킨다. 그 주소값을 이용해서 a의 값 변경
//*pa 는 다른 주소값 가리키도록 변경가능
int a = 100;
cout << "a = " << a << endl;
int* pa = &a;
*pa = 1000;
cout << "a = " << a << endl;
// b의 주소값을 저장공간하는 공간이 생기지않는
// 가리키는 방법만 추가되는 참조변수활용 int& reafa
// refa 는 현재 b의 주소값을 가리킨다. 그 주소값을 이용해서 b의 값 변경
// refa 는 처음 선언할 때 초기화 필요. 이후에 변경불가능
int b = 20;
int& refa = b;
cout << "b = " << b << endl;
refa = 2000;
cout << "b = " << b << endl;
//pa변수가 가리키는 주소값 a에서 b로변경
//*pa는 현재 b의 주소값을 가리킨다. 그 주소값을 이용해 b의 값 변경
pa = &b;
*pa = 50000;
cout << "b = " << b << endl;
return 0;
}
'Back-end > C++' 카테고리의 다른 글
22.03.16 - this 포인터, 네임맹글링(오버로딩), 배열 (0) | 2022.03.24 |
---|---|
22.03.15 - 정적 멤버 변수, 정적 멤버 함수, 함수 호출 방식 (0) | 2022.03.18 |
22.03.14 - 포인터형, 참조형, const형 변수 (0) | 2022.03.18 |
22.03.10 - 캡슐화, 객체, 접근 제어자, Set/Get함수 (0) | 2022.03.13 |
22.3.8. - 기초 개념 정의 (0) | 2022.03.13 |