월 24,200원
5개월 할부 시다른 수강생들이 자주 물어보는 질문이 궁금하신가요?
- 미해결홍정모의 따라하며 배우는 C++
M1 mac vscode 환경이고, std::execution::par 가 호출이 안됩니다.
강의 30분쯤에 나오는 코드에서 질문 있습니다. M1 Mac VSCode 환경이고, C11, C++ 17로 환경설정 다 맞췄습니다. #include<execution>도하고 강의에 나오는 코드 그대로 따라해봤지만, 해결이 되지 않아 질문드려 봅니다.
- 미해결홍정모의 따라하며 배우는 C++
대입연산자와 생성자 질문
IntArray int_array { 1, 2, 3, 4, 5 }; int_array = {6, 8, 10}; // 이 부분 주석 친 부분 디버깅 해보니까 IntArray(const std::initializer_list<int> &list): IntArray(list.size()) 여기 생성자가 실행되고나서 대입연산자 오버로딩 부분이 실행되었어요 근데 { 6 ,8, 10 } 이게 왜 IntArray 클래스 생성자가 실행되는지..? 잘 모르겠어요 int_array = {6, 8, 10}; 이게 int_array = IntArray ({6, 8, 10} ); 이것과 같은 의미인건가요?
- 미해결홍정모의 따라하며 배우는 C++
head guard가 있는데도 cpp 파일에서 body가 정의되면 에러가 뜨는 이유
따배씨를 듣고 곧바로 C++을 듣고 있습니다. 실험을 해보다 신기한 결과가 나오는데 해석이 되지 않아 질문을 남깁니다. add 함수는 add.header 파일에서 선언을 하고 add.cpp 파일에서 body를 정의하였습니다. global.h 내에 정의되어 있는 함수 print_global()은 header 파일에 Body를 정의하였습니다. 이 함수로 에러를 발생시킬 것이며 header guard가 잘 작동하는지 확인하기 위해 실험할 것입니다. global.h 함수에서 #pragma once와 #ifndef-#define으로 헤더가드를 만들면 서로 다른 cpp파일이 호출하여도 에러가 발생하지 않을거라 예상하고 실행하였습니다. // add.h #pragma once #ifndef __ADD #define __ADD int add(int a, int b); // Forward declaration, Prototype #endif // add.cpp #include "global.h" int add(int a, int b) // Definition { print_global(); return a + b; } // global.h #pragma once #ifndef __GLOBAL #define __GLOBAL #include <iostream> void print_global() { std::cout << __func__ << "is executed!" << std::endl; } #endif // !__GLOBAL // main.cpp #include "add.h" #include "global.h" int main() { print_global(); std::cout << add(1, 2) << std::endl; } 링크에러는 add.obj에서 발생하였습니다. header guard가 있어서 링크 에러가 발생하지 않아야 할 거 같은데 무슨일인지 이해가 되지 않습니다. add.cpp 파일을 지우고 add.h 헤더파일안에 함수의 Body를 넣으면 링크에러가 발생하지 않습니다. #pragma once #ifndef __ADD #define __ADD #include "global.h" int add(int a, int b) // Definition { print_global(); return a + b; } #endif 따라서 header guard가 header 파일 내부에서 정의되었더라도 cpp파일에서 #include 전처리 지시자를 사용해서 해당 header를 복사-붙여넣기 해버리면 header guard가 무용지물이 되어버린다는 가정을 세웠습니다. 제 가정이 맞나요? cpp파일에서 header guard는 작동하지 않는다는 가정이 맞나요? 왜 그런지 잘 모르겠습니다. header 파일은 link 없이 #include 전처리지시자로 동작하지만 cpp 파일은 obj로 만들어 linker가 연결해주기 때문에 전처리지시자가 아무 역할을 하지 못하는거 같습니다.
- 미해결홍정모의 따라하며 배우는 C++
입출력 오버로딩 질문이요
강의 4:48초에 나오는 friend std::ostream& operator << (std::ostream &out,const Point &point) { out << point.m_x << point.m_y << point.m_z ; } 여기서 첫번째 파라미터가 point클래스가 아니라서 member function 으로 만들기가 어렵다고 하셨는데 의미를 잘 모르겠어서 구글링하고 생각해봤는데 맞는지 여쭤보고 싶어요 멤버 함수로 만들 수 없는 이유? 를 생각해보면 << 연산자를 호출? 하는게 point 클래스 객체가 아니라서 인가요??
- 미해결홍정모의 따라하며 배우는 C++
템플릿 자동 인식 경우
템플릿 타입을 <>로 지정하지 않고, 자동으로 인식할 수 있는 경우는 int, double과 같은 기본 자료형만 해당될까요?
- 미해결홍정모의 따라하며 배우는 C++
부모클래스의 생성자 initializer_list 질문
#include <iostream> #include <cmath> #include <limits> #include <iomanip> #include <bitset> #include <string> #include <cstdint> #include <random> #include <cstddef> #include <array> #include <tuple> #include <cassert> //#include <assert.h> #include <algorithm> #include <vector> #include <chrono> #include <initializer_list> using namespace std; template <typename T, int size> class TemplateArrBase { protected: int m_length; T* m_arr; public: TemplateArrBase(const int& value = 0) : m_length(value) { m_arr = new T[value]; } TemplateArrBase(const initializer_list<T>& list) { resetArr(list.size()); int count = 0; for (const auto& element : list) { m_arr[count] = element; count++; } } T& operator [](const int& index) const { assert(index < m_length); assert(index >= 0); return m_arr[index]; } template<typename T> T sum() const { T sum = 0; for (int i = 0; i < m_length; i++) { sum += m_arr[i]; } return sum; } //1. const int operator +(const TemplateArrBase& ref) const { return this->m_length + ref.m_length; } //3. const int operator +(const int &num) const { return m_length + num; } //2. friend const int operator+(int num, const TemplateArrBase& ref) { return num + ref.m_length; } friend ostream& operator <<(ostream& out, const TemplateArrBase& over) { for (int i = 0; i < over.m_length; i++) { out.operator<<(over.m_arr[i]) << " "; } cout << endl; return out; } //template <typename T> void setArr(const initializer_list<T>& arr) { resetArr(arr.size()); int count = 0; for (const auto& element : arr) { m_arr[count] = element; count++; } } void operator = (const initializer_list<T>& list) { resetArr(list.size()); int count = 0; for (const auto& element : list) { m_arr[count] = element; count++; } } void resetArr(const int& size) { delete[] m_arr; m_arr = new T[size]; if (m_arr == nullptr) { assert(m_arr != nullptr); } m_length = size; } void print() { for (int i = 0; i < m_length; i++) { cout << m_arr[i] << " "; } cout << endl; } //friend const int operator+(const over& ref, const over& ref2) //{ // return ref.value + ref2.value; //} }; template<typename T, int size> class TemplateArr : public TemplateArrBase<T, size> { }; template<int size> class TemplateArr<bool, size> : public TemplateArrBase<bool, size> { public: void losingTicket() { } }; template<int size> class TemplateArr<char, size> : public TemplateArrBase<char, size> { public: void print() {// protected 로 선언했는데 그냥 m_length 라고 쓰면 에러뜨는 이유가 템플릿이라서 그런가요? for (int i = 0; i < TemplateArrBase<char,size>::m_length; i++) { cout << TemplateArrBase<char, size>::m_arr[i]; } cout << endl; } }; class A { public: A() { cout << "A" << endl; } }; class B : public A { public: B() { cout << "B" << endl; } void test() {} }; int main() { TemplateArrBase<int,0> over = {1,2,3,4,5}; over = { 1,2,3 }; over[1] = 32; cout << over << endl; TemplateArr<bool,10> over2; over2.losingTicket(); cout << over.sum<int>() << endl; over.print(); TemplateArrBase<char,0> over3 = { 'e','r' }; cout << over3 << endl; over3.print(); TemplateArr<char, 0> over4 = { 'a','b'}; // 에러뜨는 이유를 모르겠습니다 over4.print(); } 안녕하세요 위의 코드에 주석친것처럼 질문이 2가지가 있는데요 첫째가 템플릿이라서 상속받은 클래스들이 부모클래스의 멤버변수를 못찾는것인지에 대한 거랑 두번째로 아래 오류코드처럼 모클래스로는 initializer list 가 정상적으로 작동되는데 자식클래스로 초기화했을때는 왜 저런 에러가 뜨는지 모르겠습니다. 그래서 배열을 한개만 넣어서 초기화하면 정상작동은 하는데 문제가 문자들이 garbage 값들이 나옵니다. 모클래스 생성자도 상속받은건데 머가 문제인지 모르겠네요 ㅠㅠ
- 미해결홍정모의 따라하며 배우는 C++
10:22 생성자에서 cout 문장의 포함 여부에 따라서 왜 디버거의 행동이 달라지나요?
처음에 메모리 누수가 일어난 코드에서 cout << "Constructor " << endl; 이 문장을 안 써주면 디버깅이 안되고 쓰니까 디버깅이 되던데, 그냥 보여주는거 없이 메모리 누수만 일어나서 안썼을땐 디버거가 디버깅을 못하게 한건가요?
- 미해결홍정모의 따라하며 배우는 C++
포인터 변수끼리의 산술연산..?
int main() {int a = 3; int *ptr_a = &a;std::cout << int((ptr_a + 1) - ptr_a) << std::endl;}저 연산 결과가 4가 나올 거라고 생각했는데 1이 나오더라구요, 각각 (int)로 캐스팅할 땐 4가 나왔는데. 저 연산은 그냥 ptr_a 가 상쇄되어서 그런건가요..? 아니면 그 떨어진 간격을 결과로 나타내어서 그렇게 나오는 것인가요?
- 미해결홍정모의 따라하며 배우는 C++
객체의 사라지는 시점에 관한질문
지금까지 공부한 내용을 바탕으로 보면 객체는 생성된 괄호 안에서만 존재하고 괄호를 벗어나면 사라진다 라고 배웠습니다. 익명객체는 줄이끝나면 바로 없어지고요 근데 드는의문점이 있는데요 위의 코드에서처럼 객체의 소멸시점에 대해 실험해봤는데 실행결과만 보면 객체의 매개변수등의 정보들이 메모리에 여전히 저장되어 있는것처럼 나옵니다. 저 값들은 말그대로 os에 반납된 메모리라 언젠간 다른 데이터로 인하여 덮어질 예정인 값들이 맞죠? 저 mon1 이라는 객체는 말그대로 없어진것이 맞는지 궁금합니다. 만약에 없어진 것이 맞다면 예를들어 mon1 안에 Position2D 타입의 객체를 생성하는 구문이 있을때 이 생성된 객체도 없어지는것이 맞죠?
- 미해결홍정모의 따라하며 배우는 C++
타입 불일치 오류
#include <iostream> #include <cassert> #include <initializer_list> class IntArray { private: unsigned int m_length{ 0 }; int* m_data = nullptr; public: IntArray(unsigned length) :m_length(length) { m_data = new int[length]; } // ERROR: C4267 - 'argument': conversion from 'size_t' to 'unsigned int', possible loss of data IntArray(const std::initializer_list<int>& list) :IntArray(list.size()) { unsigned int count{ 0 }; for (auto& element : list) { m_data[count++] = element; } } ~IntArray() { delete[] this->m_data; } }; int main() { IntArray int_array{ 0,1,2,3,4 }; } 안녕하세요. MSVS debug x64 에서 빌드하면 이런 오류가 나옵니다. ---- C4267 : 'argument' - conversion from 'size_t' to 'unsigned int', possible loss of data ---- dubug x86 에서는 오류가 안나오네요. 이유가 궁금합니다. 감사합니다.
- 해결됨홍정모의 따라하며 배우는 C++
이것도 선택정렬 이라고 볼 수 있나요?
안녕하세요, 이제 뭔가 뚝딱뚝딱 해야 할것들이 늘어나는 것 같아서 점점 재밌어지네요. 머리도 복잡한건 덤 :) 교수님이 먼저 진행 하시기 전 먼저 구현을 해보라고 했을때 코드 짜본건데 결과적으로는 잘 정렬이 되었습니다. 혹시나 해서 배열 크기를 10으로 잡고 했는데도 결과는 1~10까지 오름차순 으로 잘 되었는데요, 교수님이 하신거랑 제가 한거랑 비교했을 때 차이가 크더라구요. 혹시 이것도 제대로 선택 정렬을 한 것이라 봐도 될까요? 디버깅으로 찍어봐도 제가 지금 헷갈려서 그런건지 이해가 좀 어려운것 같아요. 아래쪽 코드는 내림차순으로 나온건데 같이 첨부해 봅니다. 감사합니다. const int length = 5; int array[length] = { 3, 5, 2, 1, 4 }; cout << "current array: "; printArray(array, length); int swap = 0; for (int i = 0; i < length; i++) { for (int j = 0; j < length; j++) { if (array[i] < array[j]) { swap = array[i]; array[i] = array[j]; array[j] = swap; } //cout << array[j] << " "; } printArray(array, length); } // 5 4 3 2 1 /*for (int i = 0; i < length; i++) { for (int j = 0; j < length; j++) { if (array[i] > array[j]) { swap = array[j]; array[j] = array[i]; array[i] = swap; } cout << array[j] << " "; } cout << endl; }*/
- 미해결홍정모의 따라하며 배우는 C++
객체 배열 질문
배열로 만들어서 주소를 한번 확인해봤습니다. 근데 int는 4바이트이고 double은 8바이트인데 주소로는 16바이트의 차이가 났습니다. int랑 int로 했을때는 정상적으로 8이 되었는데 왜 이렇게 되는지 궁금합니다. 혹시 x+1이런방식이 아니고 다른 방식으로 해야 되는건지 궁금합니다
- 미해결홍정모의 따라하며 배우는 C++
적절한 생성자가 없습니다?
안녕하세요 이번 강의듣고 여러가지 실험하다가 알아내게된 사실인데요 위의 코드에서처럼 생성자가 없을시 저 리터럴값이 들어가지가 않더라고요. 이건 구글에 쳐봐도 제가원하는 답이안나와서... 사실 진짜로 알고싶은게 저 주석처리된 생성자를 풀면 코드에 에러가 사라지고 원래는 Test 클래스 객체만 받아야할 저 a 라는 함수가 리터럴값 뿐만아니라 다른 정수형도 받고 정상적으로 변수에 저장되기까지합니다... 이게 질문의 요지인데... 어떻게 이게 가능한건지 알고싶습니다. 문자의경우 아스키코드 값으로 저장이 되더라고요 그리고 아래코드에서 using namespace std; class over { int value; public: over(const int &value): value(value) {} //1. const int operator +(const over& ref) { return this->value + ref.value; } //3. const int operator +(const int &num) { return value + num; } //2. friend int operator+(int num, const over& ref) { return num + ref.value; } }; int main() { //1. 객체끼리의 연산 cout << over(1).operator+(over(2)) << endl; cout << over(1) + over(2) << endl; //2. 리터럴 + 객체 cout << 1 + over(1) << endl; //3. 객체 + 리터럴 cout << over(1) + 1 << endl; cout << 5 + over(2) + 4 + over(1) << endl; } 코드 2번 리터럴 + 객체 를 구현하기위해 저 friend 붙은 함수를 구현해야 하잖아요. 궁금한게 저 부분이 잘 이해가 되지 않거든요 객체 + 리터럴 같은경우에는 내부적으로 .operator+ => 이게 + 로 컴파일 내부적으로 바꿔주기에 충분히 이해하였는데 그렇게 따지면 저 리터럴 + 객체부분은 설명이 안되더라고요. 말이 되려면 리터럴 이런것도 컴파일 내부적으로 객체취급해 서 가능하게끔 한다는 말이어야하는데... 그냥 외워야 될려나요?? 그리고 코드 맨마지막줄의 cout << 5 + over(2) + 4 + over(1) << endl; 이부분에서요 총 + 가 3개가 있는데 원래대로라면 두번째 + 는 위 코드의 3번째 함수를 가리켜야 정상인데 아무것도 가리키고 있지 않습니다. 위 예시의 그 윗줄 코드인 cout << over(1) + 1 << endl; 여기서의 + 는 코드의 3번째 함수를 정상적으로 가리키고 있는데, 이것도 왜이런건지 잘 모르겠습니다...ㅠ 제가볼때는 원래 + 인거같은데 하지만 +를 오버로딩을 했는데.... 흠 잘모르겠네요 질문이 장난아닌데;; 답변주신 모든분들 감사합니다
- 미해결홍정모의 따라하며 배우는 C++
array<int,n> 관련 질문
4:44초 에 나오는 매개변수 array<int,5>를 보고 크기값을 바꾸면 어떻게 될까 싶어서 바꾸어봤었는데 오류가 났었습니다 ( array<int,4> 나 array<int,6> 처럼 5보다 작거나 큰값을 넣었습니다) 그래서 인수값을 형변환 해줬더니 배열은 형변환이 안된다는 듯한 오류가 떠서 궁금증이 생겼는데 Q1. array<int, n>의 크기값을 왜 바꿀수가 없나요? Q2. 배열은 형변환이 왜 안되나요?
- 미해결홍정모의 따라하며 배우는 C++
friend 전방선언 관련 질문
안녕하세요. 다음은 6:38 초에 다룬 코드입니다. #include <iostream> class B; // forward declaration class A { private: int m_value{ 1 }; friend class B; }; class B { private: int m_value{ 2 }; public: void doSomething(A& a) { std::cout << a.m_value << '\n'; } }; int main() { A a; B b; b.doSomething(a); return 0; } 여기서 forward declaration (class B;) 을 빼도 코드는 정상 작동합니다(적어도 MSVS 2019에서는 오류가 없네요). 이유가 궁금합니다. 감사합니다.
- 미해결홍정모의 따라하며 배우는 C++
생성자의 형태에 따른 출력값의 차이
그 생성자 표현방식은 2가지가 있잖아요 using namespace std; class Test { int m_value; int m_ref; public: Test(const int& value) { Test(10, value); } Test(const int& ref,const int& value) { m_ref = ref; m_value = value; } const Test& print() { cout << m_value << " " << m_ref << endl; cout << (int) & m_value << endl; return *this; } }; int main() { Test(10).print(); } 이 전체코드에서 위의 Test(const int& value) { Test(10, value); } 이 부분은 Test(const int& value): Test(10, value) {} 이거랑 같잖아요 근데 아래코드는 정상작동하는 반면에 위의 코드는 이상한 출력값이 나옵니다. 왜이런걸까요?
- 미해결홍정모의 따라하며 배우는 C++
friend bool operator < ()에서 질문 있습니다.
class Cents { private: int m_cents; public: Cents(int cents = 0) { m_cents = cents; } int getCents() const { return m_cents; } int &getCents() { return m_cents; } friend bool operator < (const Cents &c1, const Cents &c2) { return c1.m_cents < c2.m_cents; } friend bool operator != (const Cents &c1, const Cents &c2) { return bool (c1.m_cents != c2.m_cents); } friend std::ostream& operator << (std::ostream &out, const Cents ¢s) { out << cents.m_cents; return out; } }; 강의에서 이와 같이 구현을 합니다. 여기서 질문이 있습니다. bool이 붙은 friend 함수들은 Cents class의 멤버 함수로 바꿀 수가 없나요? 두가지 시도를 했는데 오류가 났습니다. 1. Cents bool operator <() 2. bool Cents operator <()
- 미해결홍정모의 따라하며 배우는 C++
연산자 오버로딩에서 this 포인터에 대한 질문입니다..
#include <iostream> using namespace std; class Cents { private: int m_cents; public: Cents(int cents = 0) { m_cents = cents; } int getCents() const { return m_cents; } // int &getCents() { return m_cents; } Cents operator + (const Cents& c2) { return (this -> m_cents + c2.getCents()); } }; int main() { Cents cents1(6); Cents cents2(8); Cents cents3(6); Cents sum; cout << (cents1 + cents2 + cents3).getCents() << endl; return 0; } class Cents 객체의 멤버 함수가 되기 위해서 operator + 함수 오버로딩이 갖을 수 있는 매개변수가 한개인 것은 알겠습니다. 그러나 이 동작과정에 대해서 제대로 이해가 안갑니다. ㅠㅠ break point를 찍어 확인해보려 하였으나, 이상하게 되더라구요 ㅠㅠ 제가 동작과정을 순서대로 말해 볼테니, 틀린게 있으면 말해주세요. 부탁드립니다. 1. main()에서 cents1 (Cents(6))객체가 실행된다. 2. Cents 객체에서 m_cents에 6을 대입한다. 3. 여기서 이해가 안갑니다. Q1. this -> m_cents 에서 이 this는 cents1의 값을 갖고 있는 건가요? Q2. Q1이 맞다면 c2.getCents()에는 cents2의 값이 들어가고 있는 건가요? Q3. Q1이 아니라면 처음에 this -> m_cents에는 0이라는 값이 들어가 있고cents1을 통해 c2.getCents()에 6이 들어가고 this 포인터를 통해 c2 인스턴스의 멤버의 m_cents에 6을 넣어주고 그 다음에 cents2의 인스턴스 멤버에 접근하여 8을 넣어주고 ... 이런 식으로 작동하나요? Q3를 요약하자면, this는 해당 Cents class의 하나의 주소를 갖고 있고 이를 다른 인스턴스 멤버 값을 계속 더해서 this의 멤버 변수에 넣어준 다음에, 이를 return 해주는 것일까요? 이해가 제대로 안되다 보니 질문하는 것도 어렵네요.. 멘토 분이 제가 무슨 말을 하는지 이해가 되실지 모르겠습니다.. break point를 여러개 찍어서 디버그를 해보아도 main문만 돌다가 이상한데로 빠지더라고요.. ㅠㅠ
- 해결됨홍정모의 따라하며 배우는 C++
형변환 관련 질문 있습니다
void* 에서 형변환을 하는 것을 보고 포인터에서 정수나 실수 등으로 형변환 또는 정수나 실수 등에서 포인터로 형변환 하면 어떻게 될까 싶어서 해봤더니 invaild type conversion 이라고 하면서 오류가 뜹니다 왜 그런건가요? 아래는 형변환을 시도해 본 코드입니다 int value = 3; int* ptr = &value; static_cast<int>(ptr); void* ptrr = &value; static_cast<int>(ptrr); static_cast<int*>(value); static_cast<void*>(value);
- 미해결홍정모의 따라하며 배우는 C++
Calc() 질문
앞부분에 Calc(10).add(10).sub(1).mult(2).print(); 요 코드가 나와있는데 자바의 익명클래스랑 개념이 비슷한건가요? 객체안만들고 일회성으로 사용하는 그런개념이죠?