월 24,200원
5개월 할부 시다른 수강생들이 자주 물어보는 질문이 궁금하신가요?
- 해결됨홍정모의 따라하며 배우는 C++
9.11 8분쯤 질문
#include <iostream> #include <cassert> using namespace std; class MyString { public: char *m_data = nullptr; int m_length = 0; public: MyString(const char *source = "") { assert(source); // 받은 문자열이 비어있진 않은가 확인 m_length = std::strlen(source) + 1; m_data = new char[m_length]; // 배열 동적할당 for (int i = 0; i < m_length; ++i) m_data[i] = source[i]; m_data[m_length - 1] = '\0'; } ~MyString() { delete[] m_data; } char* getString() { return m_data; } int getLength() { return m_length; } }; int main() { MyString hello("Hello"); cout << (int*)hello.m_data << endl; cout << &(hello.m_data) << endl; cout << hello.getString() << endl; { MyString copy = hello; cout << (int*)copy.m_data << endl; cout << &(copy.m_data) << endl; cout << copy.getString() << endl; } cout << hello.getString() << endl; return 0; } 여기에서 cout << (int*)hello.m_data << endl; 과 cout << &(hello.m_data) << endl; 의 값이 다르게 출력되는 이유가 뭔지 궁금합니다.int main() { char name[] = "jack jack"; cout << (int*)name << endl; cout << &name << endl; }이렇게 했을 때는 두 주소값이 같게 찍히는데, 위의 경우와 어떻게 다른지 궁금합니다. 그리고 main함수에서 scope를 빠져나오고, cout << hello.getString() << endl; 했을 때, 저는 Hello 라고 잘 출력이 되는데, 이건 컴파일러와 다른건가요? (강의 영상 8분 22초에서 보여지는 결과와 다르게 나옵니다.)
- 미해결홍정모의 따라하며 배우는 C++
함수와 변수에서 extern 키워드가 생략될때의 메커니즘 차이
안녕하세요, extern 키워드가 생략될때의 메커니즘이 함수와 변수에 차이가 있는 것 같은데 이해가 되지않아 질문드립니다. 우선 교수님께서 forward declaration 설명주실때,void doSomething(); 에서 앞에 extern 키워드가 생략된 것이라고, 변수도 똑같이 생략된것이라고 말씀주십니다. 하지만 제가 실험해본바로 변수는 좀 다른 것 같습니다.어떤 실험을 해봤냐면요,"Main.cpp""testGlobal.cpp"실행시키면 multiply definition 에러가 뜨는데요,Main.cpp 파일에서 g_testGlobal 을 선언할때 int로만 선언하는게 아닌 extern int로 선언하면 에러가 안뜹니다.만약 extern 키워드가 생략된 것이라는 교수님의 말씀이 맞다면, 왜 extern int g_testGlobal; 는 에러가 안뜨고 int g_testGlobal; 은 에러가 뜨는지 궁금합니다. 둘다 에러가 안떠야 extern 이 생략된게 맞지 않나요? 다음 실험도 봐보시면 좀 더 명확한데요,"Main.cpp""testGlobal.cpp" 파일에서이렇게 extern 키워드를 바꿔치기하면 또 빌드가 잘 됩니다.여기서는 하기 답변을 참고했을 때, 위 코드가 성공적으로 빌드되는 이유를 생각해봤는데요, https://www.inflearn.com/questions/102747/42-20-%EC%BD%94%EB%94%A9%EC%97%90-%EB%AC%B8%EC%A0%9C%EA%B0%80-%EC%97%86%EC%96%B4-%EB%B3%B4%EC%9D%B4%EB%8A%94%EB%8D%B0-%EB%B9%8C%EB%93%9C%EA%B0%80-%EC%95%88%EB%90%A9%EB%8B%88%EB%8B%A4 Main.cpp 에서 obj파일이 만들어질때 g_testGlobal 변수를 extern으로 선언했으므로 g_testGlobal 변수가 어딘가 저장되어있을거라는 정보를 컴파일러에게 건네주고, 그 값을 testGlobal.cpp 의 obj 파일이 링킹될때 건네 받아 사용하는것으로 이해했습니다.하지만 반대의 경우는 안되는 것이 이해가 가지 않습니다. 왜 두번째 경우에선 tetsGlobal.cpp에서 extern을 안써줘도 빌드가 되는지 모르겠습니다. 감사합니다.
- 미해결홍정모의 따라하며 배우는 C++
6.9 연습문제 의도대로 한게 맞는건가요..?
결과는 잘 나오는디..교수님 의도대로 한거인지를 모르겠어요.
- 미해결홍정모의 따라하며 배우는 C++
리턴 값으로 초기화 시 복사 생성자 호출이 안됩니다.
#include<iostream> #include<cassert> using namespace std; class Fraction { private: int m_numerator; int m_dominator; public: Fraction(int numerator, int dominator) :m_numerator(numerator), m_dominator(dominator) { assert(dominator != 0); } Fraction(const Fraction& fraction) :m_numerator(fraction.m_numerator) , m_dominator(fraction.m_dominator) { assert(fraction.m_dominator != 0); cout << "Copied" << endl; } friend std::ostream & operator << (std::ostream& out, const Fraction& fr) { out << fr.m_numerator << " / " << fr.m_dominator << endl; return out; } }; Fraction doSomething() { Fraction temp(1, 2); cout << &temp << endl; return temp; } int main() { //return값 복사 Fraction fr = doSomething(); cout << &fr << endl; return 0; }위 코드에서 복사 생성자를 호출하지 않는 이유는 뭘까요? 사용환경에 따라서 rvo를 시켜주는건가요??
- 해결됨홍정모의 따라하며 배우는 C++
9.12 강의 마지막에 내주신 숙제가 잘 이해가 안갑니다.
대입연산자를 오버로딩 해보라고 말씀하셨는데 대입연산자를 이용해서 이니셜라이저리스트로 클래스를 생성해보란 말씀이신가요? 근데 그건 이미 교수님이 강의 마지막에 되는걸 보여주신거 아닌가요?
- 미해결홍정모의 따라하며 배우는 C++
3.3 강의 후위 연산 질문
먼저 강의 정말 유익하게 잘 보았습니다.본론으로 들어가면 선생님께서는 전위 연산을 사용하였더니 4라는 결과가 나왔지만 후위 연산을 사용하니깐 결과값이 3이 나왔습니다.여기서 a는 2가 되는 것이 이해가 되지만 b는 왜 1이 되는지 의문이여서 질문글을 남깁니다.
- 해결됨홍정모의 따라하며 배우는 C++
다중 상속 시 부모 클래스 간 생성자 호출 순서가 궁금합니다.
단일 상속 시에는 member initializer list에서 부모 클래스의 생성자와 멤버 간의 순서를 바꾸어도 무조건 부모 클래스의 생성자가 먼저 호출되었었는데, 다중 상속시에는 어떤 부모 클래스의 생성자가 먼저 호출될 지 궁금해서 테스트를 해봤습니다. // USBDevice의 constructor USBDevice(long id) : m_id(id) { cout << "USB" << endl; } // ~~~ // NetworkDevice의 constructor NetworkDevice(long id) : m_id(id) { cout << "Network" << endl; }먼저 생성자의 호출 순서를 알 수 있게 간단하게 문자열을 출력하도록 수정하였습니다.class USBNetworkDevice : public USBDevice, public NetworkDevice { public: USBNetworkDevice(long usb_id, long net_id) : USBDevice(usb_id), NetworkDevice(net_id) { } };위 코드와 같은 수정하지 않은 상태에서는 USB가 먼저 출력되고 그 다음 Network가 출력되었습니다. member initializer list에서 순서를 바꾸어도 똑같았구요.class USBNetworkDevice : public NetworkDevice, public USBDevice { public: USBNetworkDevice(long usb_id, long net_id) : USBDevice(usb_id), NetworkDevice(net_id) { } };다음으로는 상속할 클래스를 나열할 때의 순서를 바꾸었더니 Network 가 먼저 출력되고 다음으로 USB가 출력되었습니다. 상속할 클래스를 나열한 순서에 따라서 생성자의 호출 순서가 바뀐다고 보면 될까요? 아 그리고 이런 생성자 호출 순서를 고려해야 하는 작업이 있나요? 객체지향적으로 설계한다면 생성자의 호출 순서에 따라 결과가 바뀌도록 설계하진 않을 것 같아서요.
- 미해결홍정모의 따라하며 배우는 C++
9.3 강의 보다가 궁금한 점
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 { return Cents(-m_cents); } bool operator ! () const { return (m_cents == 0) ? true : false; } friend std::ostream& operator << (std::ostream &out, const Cents ¢s) { out << "(" << cents.m_cents << ")"; return out; } }; int main() { Cents cents1(6); Cents cents2(0); cout << cents1 << endl; cout << cents2 << endl; cout << -cents(-10) << endl; cout << !cents1 << endl; cout << !cents2 << endl; return 0; } // 결과 (6) (0) (10) 0 1 이렇게 1~3번째와 4,5번째가 다른 이유가 궁금합니다.
- 해결됨홍정모의 따라하며 배우는 C++
if( 5 ) 자주 쓰나요?
안녕하세요, 좋은 강의 잘 듣고 있습니다.if (items_flag & opt1) 이런식으로 item1이 있는지 없는지 판단하는데,여기서 if() 안의 표현식이 0이 아닌 값으로 평가되면 true가 나온다는걸 이용하는건 알겠는데요,이 방식이 현업에서도 많이 쓰이나요?강의 초반에서도 교수님이 보는 이를 배려하는 코드, 가독성이 좋은 코드를 강조했는데, if() 안의 표현식이 0, 1, 2, 3, 4, 5 ... 등등 으로 평가되는 것보다 깔끔하게 0,1 혹은 true false 로만 평가되는게 가독성 측면에선 더 낫지 않나요?
- 해결됨홍정모의 따라하며 배우는 C++
private 안에 static 멤버변수
8.11강 3분쯤 보다가 궁금한 점이 있어 질문 남깁니다. class Something { private: static int s_value; public: int getValue() { return s_value; } } int Something::s_value = 1024;이렇게 클래스 내부에서 s_value 선언을 하고, 클래스 외부에서 초기화를 하셨는데,클래스 외부에서 private 안에서 선언된 멤버변수로 접근하는것이 불가능한것으로 알고 있는데, 이 경우는 어떻게 가능한건지 알고 싶습니다. int main() { cout << something.getValue() << endl; // cout << something.s_value << endl; // 에러 }그리고 이렇게 cout으로 출력했을 때, 아래 부분이 에러나는 이유도 궁금합니다. private 내의 static 멤버변수는 외부에서 접근이 불가능한거고, 초기화만 외부에서 해줄 수 있는건가요?
- 미해결홍정모의 따라하며 배우는 C++
#include<algorithm>없이 std:max()사용 가능
강의 5:20에서 보면std::max()는 <algorithm>이라는 라이브러리 안에 저장되어 있어서 #include로 불러와야 사용이 가능하다고 하셨습니다.#include <iostream> using namespace std; int main() { cout << std::max(100,2) << endl; return 0; }근데 왜 저는 <algorithm>을 불러오지 않아도 오류 없이 사용이 가능할까요? 궁금하네요... 감사합니다.
- 미해결홍정모의 따라하며 배우는 C++
namespace의 활용
namespace의 사용이유는std::cout, std::cin, std::in처럼 함수를 목적에 따라 분류하기 위해서 사용하는 건가요? 함수만 namespace에 저장할 수 있는 지 궁금해져서 #include <iostream> using namespace std; namespace Space1 { int a = 10; } int main() { cout << Space1::a << endl; return 0; }이렇게 입력했더니 정수형 변수 a도 namespace에 저장할 수 있었습니다.함수 이외에도 namespace를 사용하는 경우가 있을까요?? 감사합니다.
- 미해결홍정모의 따라하며 배우는 C++
함수포인터 질문 드려요!
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요.7.9강을 듣고 의문이 들었던점은포인터는 메모리를 새로 할당받는다는 단점이 있기때문에참조를 사용했는데 함수를 매개변수로 활용하고싶을때 함수포인터가 아닌참조를 사용할수도있나요?
- 미해결홍정모의 따라하며 배우는 C++
선택정렬 관하여 다른 코드
이 원리도 맞을까요? 부등호만 반대로 바꾸면 내림차순이 되는 것 같은데 비효율적이진 않은지 궁금합니다.
- 해결됨홍정모의 따라하며 배우는 C++
단항 연산자 오버로딩 방법에 대해 질문있습니다.
9.1 산술 연산자 오버로딩하기 강의에서는 연산자 오버로딩을 멤버 함수, friend 함수, 전역 함수로 구현하는 방법을 각각 알아봤었습니다. 그런데 이번 강의의 단항 연산자 오버로딩은 멤버함수로만 구현하고 전역 함수로 구현하는 내용이 없어 스스로 시도해보았습니다.https://learn.microsoft.com/en-us/cpp/cpp/overloading-unary-operators?view=msvc-170위 링크의 아래 내용을 참고하여 작성해 보았습니다.To declare a unary operator function as a nonmember function, use this declaration form:return-type operator op ( class-type ); class Cents { private: int m_cents; public: Cents(int cents) { m_cents = cents; } int getCents() const { return m_cents; } int& getCents() { return m_cents; } friend std::ostream& operator << (std::ostream& out, const Cents& cents) { out << cents.m_cents; return out; } }; // 비멤버 함수로 오버로딩 Cents operator -(const Cents& cents) { return Cents(-cents.getCents()); } int main() { Cents cents1(6); cout << cents1 << endl; cout << -cents1 << endl; // 6 // -6 return 0; }테스트는 잘 되더라구요. 이렇게 하는 것이 맞나요?
- 미해결홍정모의 따라하며 배우는 C++
7.15강 2:55 부분
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요. 2분 55초 부근에서 exe파일에 접근하여 문자열이나 숫자를 입력하는 부분을 보고 있는데혹시 vscode로 하고 있으면 어떻게 해야 하는지 알 수 있을까요?현재 저는 맥으로 하고 있으며, exe파일은 없고 폴더 안에 cpp파일만 있는 상태입니다..
- 해결됨홍정모의 따라하며 배우는 C++
함수 오버로딩 부분 (7.7강)
void print(char *value) {} void print(int value) {} int main() { print(0); print('a'); }이 부분에서 print('a')가 print(char *value) 쪽으로 인식되지 않는 이유가 궁금합니다.
- 해결됨홍정모의 따라하며 배우는 C++
const member function에 관하여 궁금한 점이 있습니다.
강의 중 아래 코드를 작성하고 난 후, 코드를 변형해 보다가 의문의 생겨 질문드립니다. class Something { public: string m_value = "default"; const string& getValue() const { cout << "const version" << endl; return m_value; } string& getValue() { cout << "non-const version" << endl; return m_value; } };영상에서 const member function은 함수 내에서 멤버 변수를 수정하지 않겠다는 의미라고 나왔습니다.그런데 해당 함수의 반환 타입에 해당하는 const를 지우자 에러가 발생합니다. const member function이 아닌 getValue()와 하는 작업이 같은데도 불구하구요.(둘 다 함수 내부에서 값을 변경하지 않음)string& getValue() const { cout << "const version" << endl; return m_value; // 오류 발생 }오류문을 검색하여 유사한 질문을 찾을 수 있었습니다.https://stackoverflow.com/questions/30146562/error-qualifiers-dropped-in-binding-reference-of-type-x-to-initializer-of-type링크의 답변을 읽고 제가 이해한 바는 다음과 같습니다 : 함수의 반환형이 참조형이라면 잠재적으로 접근하여 값을 변경할 가능성이 있는데, 본 함수는 const member function라서 함수의 멤버 변수가 변하지 않아야 하기에 이를 보장하기 위하여 수정하도록 에러를 발생시킨다고 보면 될까요?오류가 발생하던 함수의 형태에서 &와 const 둘 중 하나를 지웠을 때 에러가 사라지는 것을 보면 맞는 것 같긴 한데, 정확한 설명을 듣고 싶습니다.
- 미해결홍정모의 따라하며 배우는 C++
함수 포인터 질문
std::function<bool(const int&)> fcnptr = isEven; cout << fcnptr << endl;이 방식의 초기화에서는 오류가 뜨고bool(*fcnptr)(const int&) = isEven; cout << fcnptr << endl;이 초기화에서는 오류가 안 뜨는 이유가 궁금합니다. 뜨는 에러 :E0349 no operator matches these operands
- 미해결홍정모의 따라하며 배우는 C++
7.3 포인터에 대한 레퍼런스
7.3강 16초 부분과 관련해 질문 드립니다. void foo(int* &ptr) { cout << ptr << " " << &ptr << endl; } int main() { int x = 5; int *ptr = &x; cout << ptr << " " << &ptr << endl; foo(ptr); return 0; }여기서 foo함수의 매개변수 부분에 왜 int* ptr이 아닌 int* &ptr로 쓰는지 궁금합니다.그리고 int* &ptr부분에서 &가 의미하는 것이 주소를 말하는 것인지, 참조를 말하는 것인지 헷갈리는데 어떤게 맞는지 궁금합니다. 감사합니다.