영넌 개발로그

[C++ 기초] 포인터 Pointer / Smart Pointer / this / const pointer 본문

코딩/C++

[C++ 기초] 포인터 Pointer / Smart Pointer / this / const pointer

영넌 2020. 12. 4. 03:40

pointer

주소를 가르키는 변수타입

char int와 같은 변수 타입 뒤에 * 을 붙여 정의하고 사용한다.

 

 

dereferencing

포인터 변수 이름 앞에 *을 붙여 그 주소 안에 값을 가져오는 오퍼레이션을 의미한다.

아래 예시에서 *pa 는 10, pa는 3000을 출력한다. 

 

#include <iostream>

using namespace std;

int main() {

	int a = 10;
	cout << "a: " << a << endl;

	int* pa;

	pa = &a;

	cout << "pa : " << pa << endl;
	cout << "*pa: " << *pa << endl;

	return 0;

}

 

 

 

nullptr

c언어에서 NULL로 쓰던 값과 같이 쓴다. 

포인터를 처음 선언하고 초기화 시켜주는 값으로 쓴다. 

nullptr은 포인터(char*) 0 이고 NULL은 정수 값(int) 0과 같다.

 

 

 

배열 동적 할당

int * p = new int;  이 문장은 c언어에서 malloc함수를 쓰는 것과 같다.

예를 들어 int *p = new int [5] 라는 문장은 int *p = (int*) malloc(sizeof(int)*5); 와 같다.

 

delete p; 이 문장은 c언어에서 free(p)와 같다.

동적할당되어 배열로 선언된 포인터의 경우 delete[ ] p; 로 작성해주어야 한다.

	int* p = new int[5]; 

	for (int i = 0; i < 5; i++) {
		p[i] = i + 1;
	}

	delete[] p; 

	return 0;

 

 

 

 


 

Smart pointer  --- uique_ptr

기존 포인터 문제점 

  • 할당과 해제가 짝이 맞아야 한다. 맞지 않으면 memory leak의 가능성이 있어 문제가 생김
  • new, delete (malloc, free)

다른 언어의 해결책 

  • Java : pointer를 없앴음, 언어적으로 받혀줌, Garbage collector 사용
  • Garbage collector : 메모리 할당은 개발자가 편하게 하고 반환은 신경쓰지 않는다. 컴퓨터가 찾아서 반환시킴 (백그라운드에서 돌리는 프로그램)
  • 개발자는 편하나, 컴퓨터 CPU load 증가 (그냥 좋은 컴퓨터를 쓴다)

C++의 smart pointer 도입

  • 메모리 자동 해제 : no garbage collector --> 속도 향상  (프로그램 내에서 해결)
  • nullptr로 자동 초기화
  • delete 하면 에러!
  • 동적으로 할당받은 공간에 대해서만 사용한다. (정적에서는 안됨) 

 

공간 하나 할당

	unique_ptr<int> pa (new int);

	*pa = 30;

	cout << "*pa: " << *pa << endl;

배열 할당 

	unique_ptr<int[]> pa (new int[5]);

	for (int i = 0; i < 5; i++) {
		pa[i] = i + 1;
	}

	for (int i = 0; i < 5; i++) {
		cout << i << " " << pa[i] << endl;
	}

 

* 아래와 같이 정적으로 할당된 공간은 delete 하면 디버깅 에러가 나므로 쓰면 안됨 !!!!

	int a = 10;
	unique_ptr<int> pa (&a);

	cout << *pa << endl;

 

클래스 할당

#include <iostream>

using namespace std;

class Person
{
private:
	string name;
public:
	Person(string _name) {
		name = _name;
	}
	void showName() {
		cout << name << endl;
	}
};


int main() {

	unique_ptr<Person> pa(new Person("john"));

	pa->showName();

	return 0;

}

 

 

 


 

Pointer this

class에서 object를 만들어 내게 되는데 이 객체에서 사용할 수 있는 포인터이다. 클래스 내에서만 사용가능하다.

this는 객체 자신을 가리키는 포인터이다. inside class definition

 

* pointer  this를 이용해서 class 내에서 member variable(property)와 member function(method)를 접근 가능하다

#include <iostream>

using namespace std;

class Person
{
private:
	string name;
public:
	Person(string _name) {
		this->name = _name;
	}
	void showName() {
		cout << this->name << endl;
	}
};


int main() {
	
	Person* pa = new Person("Tom");
	pa->showName();
	delete pa;

	return 0;
}

 

 


 

const and pointer

const는 상수를 표현하는 키워드 이다. (constant의 줄임말) 값을 변경할 수 없다는 의미를 가진다.

const와 pointer가 조합이 되면 여러가지 효과를 낸다.

 

int* pa

pa라는 포인터가 있고 그 안에 주소값이 담겨져 있어서, 그 주소값으로 가면 어떤 변수가 있어서 그 값을 읽거나 변경하여 사용할 수 있다.

 

1) const int* pa

  pa가 가리키는 위치에 있는 변수의 값을 바꿀 수 없다. 읽을 수는 있다.

 

2) int* const pa

   pa에 저장된 주소 값을 바꿀 수 없다. 

   처음에 할당되면 바꿀 수 없으므로 nullptr을 쓰지 않도록 주의한다.

 

3) const int* const pa

   1)번과 2)번이 모두 적용

   pa에 저장된 주소 값과 그 주소값에 있는 값을 바꿀 수 없다.

 


const and class

 

1) member function 뒤에 const를 붙이면,

  그 함수 내에서는 member variable 의 값을 사용할 수 없다. (실수 방지) 

class Person
{
private:
	string name;
public:
	Person(string _name) {
		this->name = _name;
	}
	void showName() const {
 		//아래 주석부분 사용 불가능
		//this->name = this->name + " Nice guy";
		cout << this->name << endl;
	}
};

 

2) class 객체를 가리키는 pointer가 const이면,

   const member function만 호출할 수 있다.

class Person
{
private:
	string name;
public:
	Person(string _name) {
		this->name = _name;
	}
	void showName() const {
		cout << this->name << endl;
	}

	void showChangedName() {
		this->name = this->name + " Nice guy";
		cout << this->name << endl;
	}
};


int main() {
	
	const Person* pa = new Person("Tom");
	pa->showName();

	//아래 주석부분 사용 불가능
	//pa->showChangedName();
	delete pa;

	return 0;
}

 

 

 

Comments