new, delete, delete[]의 역할과 동적 할당의 기본 구조를 복습했다.unique_ptr, shared_ptr, weak_ptr의 차이를 배웠다.weak_ptr는 반드시 lock()으로 확인 후 사용해야 함을 이해했다.~MyClass(){} 형태의 소멸자가 객체 소멸 시 실행된다는 점을 정리했다.std::string, unique_ptr, -> 문법을 같이 복습했다.unique_ptr의 단일 소유권과 싱글턴 보장은 완전히 같은 말이 아니라는 점이 헷갈렸고, 이를 따로 정리했다.}가 생존 주기
int* ptr = new int(10) / delete ptrnew 는 무조건 포인터로 받아야 한다 why? new 의 반환값은 '주소' 이기 때문.new int[5], delete[] arr 식으로 배열인걸 표기해 줘야 함arr[i] 사용. cin >> size; // 배열 크기를 사용자로부터 입력받음
if (size > 0) {
int* arr = new int[size];
// 입력받은 크기만큼 동적 배열 생성
for (int i = 0; i < size; ++i) {
arr[i] = i * 2; // 배열 초기화
int* ptr = new int(40); // 힙 메모리에 정수 40 할당
int* ptr2 = ptr;
......
delete ptr; //ptr2 는 어캄??????
dangling pointer 발생을 방지해 주는 포인터new 와 delete를 사용하지 않는 자동 메모리 관리unique_ptr: 객체에 대한 단일 소유권 관리. 소유권 '이전' 은 가능한데 두 포인터가 한 객체를 소유는 불가능shared_ptr: 여러 포인터가 한 객체 소유 가능. Reference Count로 관리 -> 사용자가 수정 불가능한 값Reference Count 가 0이 되면 메모리 해제weak_ptr: "소유권" 개념이 없는 약한 참조Reference Count를 증가시키지 않음shared_ptr 이면 순환참조(서로가 서로를 가르킴) 가능성이 있어 메모리 누수 발생 가능weak_ptr로 하면 문제 Xshared_ptr은 관찰/소유, weak_ptr 은 관찰만= move(ptr); 로 이동ptr2 = ptr1 이 안되는거지 *ptr2 = *ptr1이 안되는건 아니다. unique_ptr<int> ptr1 = make_unique<int>(20);
// 소유권 이동 (move 사용)
unique_ptr<int> ptr2 = move(ptr1);
shared_ptr<int> ptr1 = make_shared<int>(10);
// ptr1의 참조 카운트 출력
cout << "ptr1의 참조 카운트: " <<
ptr1.use_count() << endl; // 출력: 1
// ptr2가 ptr1과 리소스를 공유
shared_ptr<int> ptr2 = ptr1;
cout << "ptr2 생성 후 참조 카운트: " <<
ptr1.use_count() << endl; // 출력: 2
// ptr2가 범위를 벗어나면 참조 카운트 감소
ptr2.reset();
cout << "ptr2 해제 후 참조 카운트: " <<
ptr1.use_count() << endl; // 출력: 1
ptr.use_count(), ptr.reset() 기억하기~MyClass(){}: 클래스 소멸 시 실행 -반드시 lock()으로 반환된 shared_ptr이 유효한지 확인 후에 사용
#include <iostream>
#include <memory>
class A {
public:
void say_hello() {
std::cout << "Hello from A\n";
}
};
class B {
public:
std::weak_ptr<A> a_ptr;
void useA() {
if (auto a_shared = a_ptr.lock()) { // 유효한지 확인
a_shared->say_hello();
} else {
std::cout << "A is no longer available.\n";
}
}
};
int main() {
std::shared_ptr<B> b = std::make_shared<B>();
{
std::shared_ptr<A> a = std::make_shared<A>();
b->a_ptr = a;
b->useA(); // A가 유효하므로 Hello 출력
} // A는 scope을 벗어나며 소멸됨
b->useA(); // A는 이미 소멸되었기 때문에 메시지 출력
}
A 클래스는 걍 함수 1개짜리 검증용 클래스.B 클래스는 멤버변수로 weak pointer a_ptr 가지고 있음. A를 가리킬 (수도 있음)lock() 을 안하면 유효할지 안할지 모름. 걍 선언은 누구나 할 수 있다 느낌?B는 멤버 함수로 useA() 를 가지고 있음.a_ptr.lock()은 std::weak_ptr(위에 위크포인터 선언할 때 썼던, <memory> 라이브러리에 속한 std) 속한 멤버함수.weak_ptr.lock()으로 쓰면 해당 weak pointer가 가리키는 주소에 대한 shared pointer를 반환함auto는 그냥 자동으로 자료형 정해달라는것. 정확히는 shared_ptr a_shared 라는 변수를 if문 안에 생성해서 얘가 "존재하냐 안하냐" 로 if문을 돌리는 거a_shared 는 그냥 if문 돌리는 동안만 살아있는 수명이 존나짧은 shared pointer다. 이 동안에만 reference count는 2.main 함수에선B 클래스에 대한 shared pointer 생성.A 클래스에 대한 shared pointer a 생성.b 포인터로 만들어진 B의 인스턴스의 a_ptr에 a 대입a 는 수명이 다한다. reference count 0이라 객체 자체도 당연히 사망a_ptr 는 weak pointer 니까useA() 사용하려 해봤자 A는 없다.int* B = A; 하지 말고int* B = new int(*A); 하라는 거임UObject: 오브젝트들. GUObjectArray = 전역에 있는 오브젝트들의 정보가 담긴 배열. 플래그로 지워도 되는지 필요없는지 관리AddToRoot(), RemoveFromRoot() 으로 루트셋 관리. RF_RootSet 플래그 있으면 절대 삭제안함RF_BeginDestroyed, RF_FinishDestoryed 플래그로 얘 지워라~얘 진짜 소멸시킴 단계UObject 기반의 시스템으로 활용가능하게 해주는. [Info] 사용자 메시지[Warning] 사용자 메시지[Error] 사용자 메시지#include <iostream>
#include <memory>
#include <string>
class Logger {
private:
int logCount=0;
public:
Logger(){
std::cout << "Logger Instance has been created" << std::endl;
}
~Logger(){
std::cout << "Logger Instance terminated. Total log count: " << logCount<< std::endl;
}
void logInfo(std::string message){
std::cout << "[INFO] " << message << std::endl;
logCount++;
}
void logWarning(std::string message){
std::cout << "[WARNING] " << message << std::endl;
logCount++;
}
void logError(std::string message){
std::cout << "[ERROR] " << message << std::endl;
logCount++;
}
void showTotalLogs(){
std::cout << "Total log count is: " << logCount << std::endl;
}
};
int main(void){
std::unique_ptr<Logger> LogInstance = std::make_unique<Logger>();
LogInstance->logInfo("System is starting.");
LogInstance->logWarning("Low disk space.");
LogInstance->logError("Unable to connect to the server.");
LogInstance->showTotalLogs();
return 0;
}
String 자료형을 받기 위해:#include <string>std::string messagemain()에선 그냥 "" 로 받으면 된다unique_ptr이 LogInstance 가 하나만 존재하게 보장하진 않지않나...?