Notice
Recent Posts
Recent Comments
Link
250x250
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 28 |
Tags
- Chunk
- Webpack
- java
- current_date
- expire_logs_days
- Regular expression
- mysql 5.5
- REACT
- 퀵소트
- regex
- upgrade
- eslint
- log4j2
- migration
- spring
- spring cloud
- git
- JavaScript
- MySQL
- Spring Batch
- npm
- update
- Node
- REACTJS
- 정규표현식
- nodejs
- Effective Java
- Express
- Effective Java 3/e
- log_bin
Archives
- Today
- Total
내 세상
[C++] 동적 메모리/ 레퍼런스 본문
728x90
반응형
C++의 new, delete 사용 예시
#include <iostream>
int main()
{
// C스타일 메모리 할당
// C : void* => int* 로 암시적 변환 가능
// C++ : void* => int* 로 암시적 변환 불가능
int *p1 = static_cast<int*>(malloc(100)); // sizeof(int)*10
free(p1);
// C++ 스타일
int *p2 = new int;
delete p2;
int* p2 = new int[10]; // 배열 버전, sizeof(int)*10;
delete[] p2; // 해지 할때도 배열 버전의 delete 사용
int* p3 = new int[10];
delete p3; // 이렇게 한다면?
// 표준 문서에서 어떻게 될거 라고 정의 한적이 없다.
// 사용하지 말아야 한다.
// "undefined(미정의 동작)"이라고 한다.
// malloc : 함수 , 크기전달, void* 반환 , 생성자 호출 안됨
// new : 연산자, 타입전달, 정확한 타입반환, 생성자 호출 됨
}
&(reference) 활용 예시
#include <iostream>
int main()
{
int n1 = 10;
int n2 = n1;
int* p1 = &n1;
int& r1 = n1; // 기존 메모리의 별칭(alias)
std::cout << &n1 << std::endl;
std::cout << &r1 << std::endl;
r1 = 100; // 결국 n1에 넣게 됩니다.
std::cout << n1 << std::endl;
// 주의사항
int* p2; // ok.. 초기화되지 않은 포인터 변수는 생성 가능
int& r2; // error. 레퍼런스 변수는 반드시 초기화가 필요하다.
// 기존 메모리를 가르키는 것이기 때문에.
}
call by value, call by pointer, call by reference
#include <iostream>
void inc1(int n) { ++n; }
void inc2(int* p) { ++(*p); }
void inc3(int& r) {
int* p = 0;
int& r2 = *p; // 레퍼런스도 null이 될 수 있다!! 최악의 코드
// 하지만 일반적인 경우에는 null reference는 체크 할 필요는 없다.
++r;
// 레퍼런스 : 안전하고 사용하기 쉬운 포인터라고도 합니다.
// "자동 deferencing 되는 포인터!!"
}
int main()
{
int a = 1, b = 1, c = 1;
inc1(a); // call by value.. 복사본 생성, 증가 안됨.
// 레퍼런스 : 포인터와 유사하게 함수인자로 메모리 정보를
// 보내고 싶을 때 사용
inc2(&b); // call by pointer.. 메모리 정보(주소) 전달, 증가됨.
// 포인터 변수는 대부분 사용시 null을 확인하는 것이 안전하다.
// 하지만 일반적인 경우에는 null reference는 체크할 필요는 없다.
// inc2(int* p) { if(p==0){} ++(*p); }
int3(c); // call by reference. 메모리에 대한 또 다른 이름 제공, 증가됨.
std::cout << a << std::endl;
std::cout << b << std::endl;
std::cout << c << std::endl;
}
const & 의 사용
#include <iostream>
struct BigData {
int data[10];
};
// call by value : 원본을 수정하지 않겠다는 약속
// void foo(int a)
//void foo(BigData a)
void foo(const BigData& a)
{
a = 10; // 원본을 수정하려고 하면 에러
// 결론 : call by value보다 const & 가 좋다 !!!!
}
int main()
{
//int x = 10;
BigData x;
foo(x); // foo 안에서는 절대 x의 값을 변경하면 안된다.
std::cout << x << std::endl; // 반드시 10 나와야 한다.
}
// 인자 값을 변경하지 않는 함수 입니다. 좋은 코드는 ?
void foo(int a) {} // 1
void foo(const int& a) {} // 2
// 함수 인자 가이드라인
// 1. 인자 값을 변경하지 않는 함수
// A. primitive type : call by value foo(int n)
// B. user define type : const reference foo(const Data& d)
//
// 2. 인자 값을 변경해야 한다면
// A. 포인터도 나쁘지 않고 foo(int* p)
// B. 레퍼런스도 나쁘지 않다. foo(int& r)
// 예전에는 A를 선호(가독성 측면), 요즘은 B를 선호(안전성 측면)
728x90
반응형
'Language > C/C++' 카테고리의 다른 글
[C/C++] const VS #define (0) | 2021.02.16 |
---|---|
[C++] nullptr (0) | 2020.01.02 |
[C++] C++스타일의 캐스팅 (0) | 2020.01.02 |
[C++] C++11/C++17 에서의 반복문/제어문 (0) | 2020.01.02 |
[C++] 함수 (0) | 2020.01.02 |