❗ New Knowledge
▪ using namespace std;는 std::를 생략하기 위해서 선언한 것
▪ min_element(arr.begin(), arr.end());
▪ std::string substr(size_t pos = 0, size_t count = std::string::npos) const;
pos: 추출을 시작할 위치 (기본값: 0).
count: 추출할 문자의 개수. 기본값은std::string::npos로, 문자열의 끝까지 추출함.
▪이동시멘틱 : operator 연산자의 하위 개념 -> 면접에서도 가장 어려운 개념(언리얼 내에서는 알아서 처리함)
▪ 생성/소멸 시기를 잘 판단해서 선언 및 생성을 어디에서 해야함
▪ new 키워드로 힙 메모리에 객체 생성한 경우 해당 객체를 가리키는 포인터를 사용해야만 접근 가능
▪ vector의 push_back은 임시 객체를 만들어서 거기에 값을 복사 후 vecotor 에 삽입함
▪ 포인터는 nullptr 값을 가질 수 있고 참조는 반드시 유효한 객체를 참조해야 함(nullptr 가질 수 없음)
1️⃣ C++ 개념 강의
🔹 TO-DO LIST 구현하기
private:
string name;
int age;
public:
Student(string studentName, int studentAge) : name(studentName), age(studentAge){}
string getName() const {
return name;
}
int getAge() const {
return age;
}
string getInfo() {
return "학생 이름: " + name + "\n학생 나이: " + to_string(age);
}
};
class StudentPrinter {
public:
void print(Student& student) {
cout << student.getInfo();
}
};
int main() {
unique_ptr<StudentPrinter> printer = make_unique<StudentPrinter>();
//프린터는 하나만 있어도 되니까 -> 이 unique 스마트 포인터 이 개념에 사용되는 게 아닌가봄
//StudentPrinter printer = StudentPrinter(); //객체 정적 생성
//StudentPrinter printer; 로만 써도 되는디
//StudentPrinter* printer = new StudentPrinter(); //객체 동적 생성 및 포인터 할당
//unique_ptr<StudentPrinter> printer = make_unique<StudentPrinter>(); //위에 업그레이드 버전
//->여기서는 main에서 객체가 생성되어 여기서만 사용되니까 굳이
Student student1 = Student("John Doe", 20);
//학생 객체 생성
//여러 학생을 생성하고 싶을 땐 vector 주로 사용
printer->print(student1);
printer.print(student1);
return 1;
}
💭자아성찰
클래스 객체이름; 만 써도 객체 생성 되는데 난 여지껏 뭘 쓰고 있었던 거지...
객체가 언제, 어디에서 사용되는지도 잘 파악해야함
🔹TO-DO LIST 구현하기
#include <iostream>
#include <vector>
#include <string>
using namespace std;
class Task {
private:
string description;
bool completed = false;
public:
Task(string desc) : description(desc) {};
void complete() {
if (!completed)
completed = true;
}
string getDescription() const {
return description;
}
bool isCompleted() const {
return completed;
}
};
class IStorage {
public:
virtual void addTask(Task task) = 0;
virtual vector<Task> getTasks() = 0;
virtual string getStorageType() = 0;
};
class TaskManager {
IStorage* storage;
public:
TaskManager(IStorage* s) : storage(s) {}
//레퍼런스가 아닌 포인터로 받은 이유가 있나? -> 포인터로 받으면 nullptr을 가질 수 있음
//레퍼런스는 항상 유효한 객체를 요구함
//만약 IStorage가 항상 유효하고 TaskManager가 객체의 생명 주기를 관리하지 않는다면 레퍼런스 사용이 괜찮
// 새로운 할 일 추가
void addTask(const string& description) {
storage->addTask(Task(description));
}
// 현재 할 일 목록 출력
void showTasks() {
cout << "저장 방식: " << storage->getStorageType() << "\n";
vector<Task> tasks = storage->getTasks(); //함수 내에서만 사용되니까 함수에서 생성
for (size_t i = 0; i < tasks.size(); ++i) {
cout << i + 1 << ". " << tasks[i].getDescription();
if (tasks[i].isCompleted()) cout << " [완료]";
cout << "\n";
}
}
// 특정 할 일을 완료 처리
void completeTask(size_t index) {
vector<Task> tasks = storage->getTasks();
if (index > 0 && index <= tasks.size()) {
tasks[index - 1].complete();
storage->addTask(tasks[index - 1]); // 변경된 할 일 저장
}
else {
cout << "잘못된 번호입니다.\n";
}
}
};
class MemoryStorage : public IStorage{
vector<Task> tasks;
void addTask(Task task) {
tasks.push_back(task);
}
vector<Task> getTasks() {
return tasks;
}
string getStorageType() {
return "메모리 저장소";
}
};
class DBStorage : public IStorage {
vector<Task> tasks;
void addTask(Task task) {
//만약 여기에서
tasks.push_back(task);
cout << "DB에 할 일 추가: " << task.getDescription() << endl;
}
vector<Task> getTasks() {
return tasks;
cout << "DB에서 할 일 가져오기" << endl;
}
string getStorageType() {
return "DB 저장소 (시뮬레이션)";
}
};
// 메인 함수
int main() {
cout << "=== MemoryStorage로 작업 ===\n";
MemoryStorage memoryStorage;
TaskManager manager1(&memoryStorage);
manager1.addTask("C++ 과제 작성하기");
manager1.addTask("SOLID 원칙 공부하기");
cout << "\n현재 할 일 목록:\n";
manager1.showTasks();
manager1.completeTask(1);
cout << "\n업데이트된 할 일 목록:\n";
manager1.showTasks();
cout << "\n=== DBStorage로 작업 ===\n";
DBStorage dbStorage;
TaskManager manager2(&dbStorage);
manager2.addTask("DB 작업 테스트");
manager2.addTask("To-Do 목록 추가");
cout << "\n현재 할 일 목록:\n";
manager2.showTasks();
manager2.completeTask(2);
cout << "\n업데이트된 할 일 목록:\n";
manager2.showTasks();
return 0;
}
💭자아성찰
const & 사용하기!
'TIL' 카테고리의 다른 글
[250102 TIL] switch반복문에 열거형 입력 (0) | 2025.01.02 |
---|---|
[241231 TIL] 언리얼 C++ 한글 폰트 깨짐 (1) | 2024.12.31 |
[241227 TIL] C++ 공부_자료형의 오버플로우 (3) | 2024.12.27 |
[241226 TIL] C++ 공부_입력 예외 처리 (0) | 2024.12.26 |
[241224 TIL] Git 사용방법, C++ 공부_포인터 (0) | 2024.12.24 |