개념을 좀 급하게 배운 감이 없잖아 있었는데 실습, 예제를 풀다보면 전에 개념도 다시보게 돼서 더 잘 알게 되는 것 같음. 개념이란게 체인처럼 하나를 깨달으면 나머지도 줄줄인처럼 하나를 깨달으면 나머지도 연쇄작용으로 이해하기 쉬워짐.
C++ 문법 2주차 숙제, 객체지향 설계 실습, 알고리즘 2문제
vector<Movie> movies;
map<string, double> movieMap;
movies = {
{"Inception", 9.0},
{"Interstellar", 8.6},
{"The Dark Knight", 9.1},
{"Memento", 8.4}
};
for(const auto& movie : movies){
movieMap[movie.tilte] = movie.rating;
}
for의 처음 보는 모습에 좀 많이 당황스러웠다. const auto& movie : movies 는 어떤 것이며 스코프 안에 적힌 것은 또 뭐지?
for(const auto& movie : movies)는 쉽게 말해서
const auto& movie = movies[i] movies를 다 돌겠다는 뜻
insert는 기존에 들어있는 데이터를 '원본'으로 간주하고 보호해야 할 때 사용.struct Movie{
string title;
double rating;
};
편함 함수도 있고 안에 구구절절 내용을 적는다면 Class도 있는데 굳이 왜 구조체를 써야할까 생각했다.
"Class 안에는 변수, 함수, 상속하는 다른 파생클래스 등등 있는데.." Class를 보면 이런게 먼저 보인다. Struct(구조체)는 봤을때
"아 이건 변수 몇개를 모아서 담아 놓은 택배상자구나"
구조체는 다른 어떤 곳에서도 접근 가능한 변수를 모아서 정리해 둔 택배상자이다. 물론 Struct 역할을 할 수 있는 Class를 생성해도 되겠지만, 코드의 가독성과 관습이 있기 때문에 구조체를 사용한다.
class MovieManager {
private:
vector<Movie> movies;
map<string, double> movieMap;
public:
MovieManager() {
// 초기 데이터 설정
movies = {
{"Inception", 9.0},
{"Interstellar", 8.6},
{"The Dark Knight", 9.1},
{"Memento", 8.4}
};
for (const auto& movie : movies) {
movieMap[movie.title] = movie.rating;
}
}
처음부터 movieMap에 넣어서 KEY를 tilte로 VALUE를 rating으로 관리 했으면 되는 것 아닌가? 라고 생각이 들었다. 그럼 그냥 sort도 되고 반복문을 사용하여 굳이굳이 넣어줄 필요가 없지않나?
일단 각 컨테이너의 성질부터 봐야한다.
vector<Movie>= 데이터의 원본 보관. 넣은 순서가 그대로 유지됨 순서대로 정렬가능.
mapMap<string, double>= 검색 전용 인덱스. 제목(KEY)만 입력하면 바로 평점(VALUE)가 나옴
된다. 그렇게 쓸 수도 있고 하지만, 여기서 중요한 것은
"이 클래스는 검색하는 기능만 필요한 클래스가 아니란거다."
다기능이 필요한 클래스이기 때문에 컴퓨터와 프로그래머 둘 다 인식하기 편한 숫자로 정렬해서 두면 나중에 찾기도 편하고 관리하기에도 용이하기 때문이다.
그리고 map은 KEY로 VALUE를 찾기 때문에 VALUE 순으로 정렬하는 즉, VALUE 순으로 KEY를 정렬하는 것은 불가능하다. WHY? 평점(VALUE)는 똑같이 9.0일 수 있지만 KEY(STRING)은 중복되면 안되는 '영화의 이름'이기 때문이다.
bool compareMovies(vector<Movie>& movies)
bool compareMovies(){
vector<Movie> movies;
}
함수 안에서 선언 해두는 것과 매개변수로 받는거랑 어차피 vector<Movie> 에 참조하는거고 movies라고 부르는 별명만 바뀌는데 굳이 매개변수로 받아야할까? 라고 생각했음
영화 데이터는 DB나 파일에 딱 하나 있고, 그걸 불러와서 보여주기만 하면 끝이라고 생각했다. 보여줄 수 있는 데이터도 DB 딱 하나라고 생각했음.
vector<Movie> userFavorite; // 내가 찜한 영화 (3개)
vector<Movie> topChart; // 현재 인기 순위 (100개)
vector<Movie> searchResult; // 방금 검색한 결과 (15개)
근데 이렇게 나뉜다면?
모두 vecotr<Movie> 이지만 내용물이 다르다.
매개변수로 vector의 다른 변수들을 받을 필요가 없다고 한 것은 아직 클래스, 객체, 인스턴스의 개념을 정확히 이해하지 못한채로 내용물이 똑같고 공유하는 변수들을 선언한다고 생각했기 때문 즉,
"메모리 설계도를 그리면서 공부하지 않은것."
클래스 (Class): 설계도이자 규격
클래스는 메모리에 존재하지 않는 '생각의 틀'입니다."이런 모양이어야 해" (데이터 없음)
객체 (Object): 설계도로 구현된 모든 것
메모리 어딘가에 자리를 잡고 앉아 있는 실제 데이터 덩어리, 메모리에 실제로 만들어진 녀석 (데이터 있음)
인스턴스 (Instance): '관계'에 집중한 이름
객체와 인스턴스는 사실상 같은 것을 가리키지만, 말하는 맥락이 다름.
"이 객체는 저 클래스 출신이야"라고 부를 때 쓰는 명칭
결론은 객체라는 메모리가 있으면, 클래스라는 많은 데이터를 담고 있는 상자 이름을 붙인게 변수 vector<Movie> A1;
그래서 클래스를 담은 상자의 이름은 여러개가 나올수가 있고(변수), vector<Movie> A1, vector<Movie> A2는 서로 다른 박스에 다른 이름을 붙인 vector<Movie>라는 내용물만 같은 박스 생성. 쇼핑몰에서 옷을 파는데, 옷을 사면 다 똑같은 옷이고 모두가 공유해서 입는 옷이 아니다.
vector<Movie> f1;
vector<Movie> f2;
예시: > f1은 객체입니다. 그런데 f1은 vector 클래스의 인스턴스입니다. (f1은 vector라는 설계도로부터 구체화된 사례라는 뜻입니다.) 라고 AI가 친절하게 설명하는 것을 보고
"f1은 변수인데? 메모리 어딘가에 자리를 잡고 앉아 있는 실제 데이터 덩어리가 객체라면, 그 객체를 부르는 변수도 객체라고 부르는건가?"
결론부터 말하면 변수는 객체가 아니다.
Why? 애초에 객체가 무엇인지 착각을 하고 있는 것, 객체라는 것은 클래스 변수에 모든게 할당 되는 공간이 아니기 때문
예를 들어서 A라는 객체가 할당이 됐는데 거기에 있는게 vector<Movie> a도 있고 vector<Movie> b도 있고 vector<Movie> a1도 있고 하는거라 객체는 메모리위에 올라와 있는 데이터들을 의미함. 즉, 객체에 올라탄 변수인 것
vector<Movie> f1과 vector<Movie> f2가 같은 Class를 가지고 있을 수 있을까? 궁금해졌음 결과는
vector<Movie> f1; // 객체 A가 생기고, f1이 그 위에 올라탐
vector<Movie>& ref = f1; // 새로운 객체는 없지만, f1이 타고 있는 객체 A에 ref도 같이 올라탐
f1을 참조복사해주면 된다. 참 쉬움
개념 정리를 조금씩 하면서 가면 도움이 될 것 같음
- vec.push_back(tasks) => vec라는 배열칸에 tasks라는 값을 넣겠다
- vec.push_back(new Task(tasks)) => vec라는 배열칸에 Task크기의 tasks를 담은 주소값 을 넣겠다