고급 포인터 주제
2025. 3. 28. 08:45ㆍProgramming Languages/C++
6.5 고급 포인터 주제
6.5.1 포인터와 const
포인터와 const 키워드의 조합으로 다양한 상황을 표현할 수 있습니다:
#include <iostream>
int main() {
int value = 42;
int another = 100;
// 1. 상수 포인터 (포인터 자체가 상수)
int* const constPtr = &value;
*constPtr = 50; // 값 변경 가능
// constPtr = &another; // 오류: 포인터를 다른 주소로 변경 불가
// 2. 상수에 대한 포인터 (가리키는 값이 상수)
const int* ptrToConst = &value;
// *ptrToConst = 60; // 오류: 가리키는 값 변경 불가
ptrToConst = &another; // 다른 주소 가리키기 가능
// 3. 상수에 대한 상수 포인터 (둘 다 불변)
const int* const constPtrToConst = &value;
// *constPtrToConst = 70; // 오류: 값 변경 불가
// constPtrToConst = &another; // 오류: 주소 변경 불가
std::cout << "value: " << value << std::endl; // 50
return 0;
}
6.5.2 함수 포인터
함수 포인터는 함수의 주소를 저장하고 호출할 수 있는 포인터입니다:
#include <iostream>
#include <string>
// 함수 원형
int add(int a, int b) {
return a + b;
}
int subtract(int a, int b) {
return a - b;
}
int multiply(int a, int b) {
return a * b;
}
int divide(int a, int b) {
return b != 0 ? a / b : 0;
}
int main() {
// 함수 포인터 선언
int (*operation)(int, int);
// 함수 포인터에 함수 할당
operation = add;
std::cout << "덧셈 결과: " << operation(5, 3) << std::endl; // 8
operation = subtract;
std::cout << "뺄셈 결과: " << operation(5, 3) << std::endl; // 2
operation = multiply;
std::cout << "곱셈 결과: " << operation(5, 3) << std::endl; // 15
operation = divide;
std::cout << "나눗셈 결과: " << operation(6, 3) << std::endl; // 2
// 함수 포인터 배열
int (*operations[4])(int, int) = {add, subtract, multiply, divide};
std::string opNames[4] = {"덧셈", "뺄셈", "곱셈", "나눗셈"};
for (int i = 0; i < 4; i++) {
std::cout << opNames[i] << " 결과: " << operations[i](10, 5) << std::endl;
}
return 0;
}
함수 포인터는 콜백, 전략 패턴, 플러그인 아키텍처 등에 유용합니다.
6.5.3 다차원 배열과 포인터
다차원 배열을 포인터로 다루는 방법:
#include <iostream>
int main() {
// 2차원 배열
int matrix[3][4] = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
};
// 포인터로 접근
int (*ptr)[4] = matrix; // 4개의 정수 배열에 대한 포인터
// 첫 번째 행의 요소 출력
for (int j = 0; j < 4; j++) {
std::cout << ptr[0][j] << " "; // 1 2 3 4
}
std::cout << std::endl;
// 포인터 증가로 다음 행에 접근
ptr++;
for (int j = 0; j < 4; j++) {
std::cout << ptr[0][j] << " "; // 5 6 7 8
}
std::cout << std::endl;
// 이중 포인터를 사용한 동적 2차원 배열 할당
int rows = 3, cols = 4;
int** dynamicMatrix = new int*[rows];
for (int i = 0; i < rows; i++) {
dynamicMatrix[i] = new int[cols];
// 각 행 초기화
for (int j = 0; j < cols; j++) {
dynamicMatrix[i][j] = i * cols + j + 1;
}
}
// 동적 2차원 배열 출력
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
std::cout << dynamicMatrix[i][j] << " ";
}
std::cout << std::endl;
}
// 동적 2차원 배열 해제 (순서 중요!)
for (int i = 0; i < rows; i++) {
delete[] dynamicMatrix[i];
}
delete[] dynamicMatrix;
return 0;
}
6.5.4 멤버 포인터
클래스의 멤버 변수나 멤버 함수를 가리키는 포인터:
#include <iostream>
#include <string>
class Person {
public:
std::string name;
int age;
Person(const std::string& n, int a) : name(n), age(a) {}
void introduce() {
std::cout << "안녕하세요, 제 이름은 " << name << "이고 "
<< age << "살입니다." << std::endl;
}
void celebrateBirthday() {
age++;
std::cout << "생일 축하합니다! 이제 " << age << "살이 되었습니다." << std::endl;
}
};
int main() {
// 멤버 변수 포인터
std::string Person::*namePtr = &Person::name;
int Person::*agePtr = &Person::age;
// 멤버 함수 포인터
void (Person::*introducePtr)() = &Person::introduce;
void (Person::*birthdayPtr)() = &Person::celebrateBirthday;
// 객체 생성
Person person("홍길동", 25);
// 멤버 변수 포인터 사용
std::cout << "이름: " << person.*namePtr << std::endl;
std::cout << "나이: " << person.*agePtr << std::endl;
// 멤버 변수 포인터로 값 변경
person.*namePtr = "김철수";
person.*agePtr = 30;
// 멤버 함수 포인터 사용
(person.*introducePtr)();
(person.*birthdayPtr)();
// 포인터를 통한 멤버 접근
Person* personPtr = &person;
std::cout << "포인터를 통한 이름: " << personPtr->*namePtr << std::endl;
(personPtr->*introducePtr)();
return 0;
}
멤버 포인터는 일반 포인터보다 복잡하지만, 런타임에 클래스의 특정 멤버를 선택하는 등의 고급 기법에 유용합니다.
'Programming Languages > C++' 카테고리의 다른 글
템플릿 (0) | 2025.03.28 |
---|---|
챕터6. 실습 문제 (0) | 2025.03.28 |
참조 (0) | 2025.03.28 |
동적 메모리 할당 (0) | 2025.03.28 |
포인터의 기본 (0) | 2025.03.28 |