월 24,200원
5개월 할부 시다른 수강생들이 자주 물어보는 질문이 궁금하신가요?
- 미해결홍정모의 따라하며 배우는 C++
class Derived : private Base일 경우질문
class Derived : private Base { public: Derived() { // private Base Base::m_public; // 손자 클래스에서 사용 불가 Base::m_protected; // 손자 클래스에서 사용 불가 // x Base::m_private; // 사용 불가 } };안녕하세요. 항상 고생 많으십니다.해당 코드에서class Derived : private Base가 되면. class Derived 내에서,Base::m_private는 당연히 접근이 불가능한 것은 맞는데 나머지Base::m_public; Base::m_protected; 에 대해서는 Derived내에서 접근이 가능한가요?손자 클래스에서는 접근이 불가능하다는 것을 말씀 해주셔서 이해 했는데, 자식 클래스에서는 접근 여부가 어떻게 될까요?
- 미해결홍정모의 따라하며 배우는 C++
익명객체 생성자호출
안녕하세요! 15:40경입니다. 간단한 궁금증이 있는데Monster mon1("Sanson", Position2D(0,1));교수님께서 위와같이 main함수 내에, 매개변수에 있는 것들로 Monster 클래스의 mon1의생성자를 호출하셨습니다.Monster클래스의 생성자는 아래와 같고,Monster(const std::string name_in, const Position2D & pos_in) : m_name(name_in), m_location(pos_in) {}스트링 문자열과, Position2D객체를 파라미터로 받는데요 Q) 이때 저 위에 있는Monster mon1("Sanson", Position2D(0,1));의 Position2D(0,1)는 익명객체이고 자신을 참조하는 레퍼런스const Position2D & pos_in에게 주소를 넘겨주고 생성자에 의해 private멤버 변수가 값복사에의한 초기화가 끝나는 즉시 Position2D(0,1)는 사라진다는 설명이 적절할까요? 감사합니다
- 미해결홍정모의 따라하며 배우는 C++
Assignment Operator의 delete[]
안녕하세요 9.11 13:50 부근입니다MyString& operator = (const MyString& source) { cout << "Assignment operator " << endl; if (this == &source) // prevent self-assignment return *this; delete[] m_data; m_length = source.m_length; if (source.m_data != nullptr) { m_data = new char[m_length]; for (int i = 0; i < m_length; ++i) m_data[i] = source.m_data[i]; } else m_data = nullptr; return *this; }해당 코드는 클래스 MyString의 대입연산자 입니다.가운데에 보시면 delete[] m_data;가 보이실텐데 교수님이 m_data가 이미 메모리를 가지고있었을 수도 있다고 하시는데 그 어떤 증례도 떠오르지 않습니다. int main함수 내에서{ MyString copy = hello; cout << (int*)copy.m_data << endl; cout << copy.getString() << endl; }다음과같이 copy가 그냥 여기서 처음 생기고 scope를 벗어나면 사라지는데이 이전에 copy의 m_data가 메모리를 가지고 있었다고 하는 것이 납득이 되지 않아서 간단한 설명 부탁드리고싶습니다. 감사합니다. ++수정)질문 작성 도중에 떠올랐는데 교수님이 말씀하신 케이스가이미 옛적에 copy를 만들어서 쓰고있었지만 그 본 것을 버리고 새로 다른 데에 쓰려고 새로 인스턴스를 대입해준다는 말씀이셨을까요? (--> 따라서 delete함으로써 전에 쓰던 주소를 계속 이어씀으로써 발생할 수 있는 UB를 방지??) (전체코드) #include <iostream> #include <cassert> using namespace std; class MyString { //private: 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(const MyString& source) { cout << "Copy constructor " << endl; m_length = source.m_length; if (source.m_data != nullptr) { m_data = new char[m_length]; for (int i = 0; i < m_length; ++i) m_data[i] = source.m_data[i]; } else m_data = nullptr; } MyString& operator = (const MyString& source) { cout << "Assignment operator " << endl; if (this == &source) // prevent self-assignment return *this; delete[] m_data; m_length = source.m_length; if (source.m_data != nullptr) { m_data = new char[m_length]; for (int i = 0; i < m_length; ++i) m_data[i] = source.m_data[i]; } else m_data = nullptr; return *this; } ~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.getString() << endl; { MyString copy = hello; cout << (int*)copy.m_data << endl; cout << copy.getString() << endl; } cout << hello.getString() << endl; return 0; }
- 미해결홍정모의 따라하며 배우는 C++
증감연산자 오버로딩
안녕하세요 궁금한 것이 있어 여쭤봅니다 교수님께서 전위증가연산자 오버로딩 코드를 이렇게 짜셨습니다.class Digit { private: int m_digit; public: Digit(int digit = 0) : m_digit(digit) {} //prefix Digit& operator ++ () { ++m_digit; return *this; } friend ostream& operator << (ostream& out, const Digit& d) { out << d.m_digit; return out; } };아래는 main 함수 부분이고요int main() { Digit d(5); cout << ++d << endl; cout << d << endl; return 0; }여기 멤버함수로 구현이 돼있는데요Digit& operator ++ () { ++m_digit; return *this; }cout << ++d << endl; 에서 d를 만난다음 d가 ++연산자를 호출할텐데 ++m_digit;이렇게 d인스턴스의 m_digit을 바로 1증가 시켜준다면 그냥 여기서 끝나면 되는 것 아닌가요? 인스턴스d가 호출한 ++연산자에서 인스턴스d의 m_digit을 직접 1증가 시켜줬는데, 위에서 operator ++ 왼쪽에 적혀 있는 리턴형인 Digit&과 리턴하는 값인 return *this;가 대체 무엇을 하는지 그 작동과정이 전혀 감이 안 잡혀서 구글링도 하고 그랬는데 원하는 것을 얻지 못한 거 같습니다 ㅠㅠ자세한 설명 부탁드려도 될까요?감사합니다
- 해결됨홍정모의 따라하며 배우는 C++
클래스 멤버 함수에 대한 질문
안녕하세요!이번 강의에 대해 이해가 어려운 부분이 있어서 질문드립니다.1분 10초 쯤부터 교수님께서 이렇게 말씀하십니다.''setID와 getID는 함수인데, 그렇다면 이 함수들이 s1과 s2에 각각 따로 들어가 있을까?""그렇지 않다. 하나를 만들어놓고 중복해서 사용한다.""Simple 이라는 클래스의 모두가 공유해서 사용한다"그렇다면, s1과 s2에서 사용하는 setID와 getID의 주소는 같다는 것일까요?같다면, 어떻게 출력으로 확인해볼 수 있나요?질문이 많이 부족하지만 늘 많은 도움 주셔서 감사드립니다.- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요.
- 미해결홍정모의 따라하며 배우는 C++
class 생성자 함수 오버로딩
안녕하세요. 8.5강 3:55 부근입니다. 교수님께서//아래는 Student Class의 생성자들입니다. Student(const string& name_in) //: m_id(0), m_name(name_in) : Student(0, name_in) {} Student(const int& id_in, const string& name_in) : m_id(id_in), m_name(name_in) {} ... 와 같이 Student 클래스에 생성자 두 개를 만드셨습니다. 이때, 아래와 같이 Student클래스에 대한 인스턴스가 각각 st1, st2이렇게 있는데요int main() { Student st1(0, "Jack Jack"); st1.print(); Student st2("Dash"); st2.print(); return 0; }st1는 Student st1(0, "Jack Jack"); 와 같이 (표현이 올바른지는 모르겠습니다 -->) 생성자 함수를 int와 string 두 개의 매개변수로 호출하는데, 이때, 이름이 같은 생성자 함수가 여러개 있음에도 함수 오버로딩을 통해 int와 string을 매개변수로 가지는 생성자 함수를 알아서 찾게 됨으로써Student(const int& id_in, const string& name_in) : m_id(id_in), m_name(name_in) {}의 생성자만 단독으로 호출되는 원리인가요? 감사합니다.
- 해결됨홍정모의 따라하며 배우는 C++
함수 reference 반환
안녕하세요 궁금증이 생겨 하나 여쭤봅니다.7.5강 8:42 부근입니다.int& getValue(int x) { int value = x * 2; return value; } int main() { int &value = getValue(5); cout << value << endl; cout << value << endl; ...return value; 에서 getValue함수의 반환값은 int 레퍼런스 형이니 main함수의 int &value = getValue(5); 부분에서호출자 getValue(5)는 int &~ = value;에서 ~의 부분에 해당하나요? 그렇다면 getValue에 있던 value 변수의 레퍼런스인데그렇게 되면 int &value = getValue(5);는 레퍼런스의 레퍼런스라 오류가 발생해야하는 것이 아닌가요? 감사합니다.
- 미해결홍정모의 따라하며 배우는 C++
short circuit evaluation
#include <iostream> using namespace std; int main() { //short circuit evaluation int x = 2; int y = 2; if (x == 1 && y++ == 2) { cout << "good" << endl; } cout << y << endl; return 0; }강의 18:05에서마지막에 y값이 2로 출력되는 이유가&&연산자는 왼쪽을 계산했을 때 false면 오른쪽을 계산하지않는다고 하셨습니다.if (x == 1 && y++ == 2)근데 이 문장에서 연산자 우선순위를생각해보면 y++ > == > &&니까 y++(후위증가연산자)먼저 되서 y는 이 문장이 끝나면 어쨌든 1이 증가되야하는것 아닌가요?그 후 그다음 연산자 우선순위인 ==, &&순으로 진행되어야 하지 않나요?제가 잘못이해한걸까요?
- 해결됨홍정모의 따라하며 배우는 C++
(과제스포)제가 과제를 똑바로 이해했는지 궁금합니다.
#include<chrono> #include<iostream> #include<mutex> #include<random> #include<thread> #include<utility> #include<vector> #include<atomic> #include<future> #include<numeric> #include<execution> using namespace std; mutex mtx; void dotProductDQThread(const vector<int>& v0, const vector<int>& v1, const unsigned i_start, const unsigned i_end, unsigned long long& sum) { int sum_tmp = 0; //local sum for (unsigned i = i_start; i < i_end; ++i) { sum_tmp += v0[i] * v1[i]; } sum += sum_tmp; } void dotProductProm(const vector<int>& v0, const vector<int>& v1, const unsigned i_start, const unsigned i_end, promise<unsigned long long>&& sum) { int sum_tmp = 0; //local sum for (unsigned i = i_start; i < i_end; ++i) { sum_tmp += v0[i] * v1[i]; } sum.set_value(sum_tmp); } int main() { /*v0 = { 1,2,3 }; v1 = { 4,5,6 }; v0_dot = 1 * 4 + 2 * 5 + 3 * 6;*/ const long long n_data = 100'000'000; const unsigned n_threads = 4; //initialize vectors std::vector<int> v0, v1; v0.reserve(n_data); v1.reserve(n_data); random_device seed; mt19937 engine(seed()); uniform_int_distribution<> uniformDist(1, 10); //v0와 v1에 값 무작위로 넣어줌 for (long long i = 0; i < n_data; ++i) { v0.push_back(uniformDist(engine)); v1.push_back(uniformDist(engine)); //cout << v0[i] << "\t" << v1[i] << endl; } cout << "std::inner_product" << endl; { const auto sta = chrono::steady_clock::now(); const auto sum = std::inner_product(v0.begin(), v0.end(), v1.begin(), 0ull);//0ull = unsigned longlong 0 const chrono::duration<double> dur = chrono::steady_clock::now() - sta; cout << dur.count() << endl; cout << sum << endl; cout << endl; } //TODO: use divde and conquer strategy for std::thread cout << "TODO: use divde and conquer strategy for std::thread" << endl; { const auto sta = chrono::steady_clock::now(); unsigned long long sum = 0; vector<thread> threads; threads.resize(n_threads); const unsigned n_per_thread = n_data / n_threads; for (unsigned t = 0; t < n_threads; ++t) threads[t] = std::thread(dotProductDQThread, std::ref(v0), std::ref(v1), t * n_per_thread, (t + 1) * n_per_thread, std::ref(sum)); for (unsigned t = 0; t < n_threads; ++t) threads[t].join(); const chrono::duration<double> dur = chrono::steady_clock::now() - sta; cout << dur.count() << endl; cout << sum << endl; cout << endl; } //TODO: use promise cout << "TODO: use promise" << endl; { const auto sta = chrono::steady_clock::now(); //std::promise<unsigned long long> sum; auto sum = 0ull; vector<thread> threads; vector<future<unsigned long long>> futures; vector<promise<unsigned long long>> proms; threads.resize(n_threads); futures.resize(n_threads); proms.resize(n_threads); const unsigned n_per_thread = n_data / n_threads; for (unsigned t = 0; t < n_threads; ++t) { futures[t] = proms[t].get_future(); threads[t] = std::thread(dotProductProm, std::ref(v0), std::ref(v1), t * n_per_thread, (t + 1) * n_per_thread, std::move(proms[t])); } for (unsigned t = 0; t < n_threads; ++t) { threads[t].join(); sum += futures[t].get(); } const chrono::duration<double> dur = chrono::steady_clock::now() - sta; cout << dur.count() << endl; cout << sum << endl; cout << endl; } }결과는 제대로 나오지만, 제가 과제를 똑바로 이해했는지 궁금해서 여쭤봅니다.과제1: use divde and conquer strategy for std::thread쓰레드에 sum에 local sum값을 넣어 race condition 해결과제2: prom 사용해보기sum 변수 선언 및 thread, promise, future 모두 쓰레드 크기 만큼의 vector로 만들어줬습니다. 병렬 처리 후 future값을 sum에 더해줬습니다.※추가 궁금증promise 과제 중, std::ref와 std::move 둘 다 해보았습니다. 두 경우 모두 정상 작동하였는데, 어떤 방법을 가장 추천하시나요?
- 미해결홍정모의 따라하며 배우는 C++
헤더파일 포함 컴파일 방법
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아헤더 파일을 포함한 파일에 대해 컴파일하는 방법이 궁금합니다.다른 분 답변에서는 makefile을 사용하라고 다른 분께서 말씀하시던데 이해가 되지 않아 남겨봅니다.
- 미해결홍정모의 따라하며 배우는 C++
\n과 endl의 차이
강의 19:25를 보면 '\n'은 단순 줄 바꿈이고 'endl'의 경우 줄을 바꿈과 동시에 버퍼에 있는 모든 것을 출력한다고 하셨습니다. #include <iostream> using namespace std; int main() { char c1; cin >> c1; cout << c1 << endl; return 0; }제가 간단하게 예제를 만들었습니다.실행 후에 c1에 입력을 단순히 하나의 문자가 아니라 12345처럼 문자열을 넣으면 c1에는 1이 담기고 2345는 버퍼에 저장된다고 생각했습니다.endl;이 버퍼에 있는 모든 것을 출력하니까 12345 모두 출력될 줄 알았는데 1만 출력되었습니다.제가 잘못 이해한 것일까요? 감사합니다.
- 미해결홍정모의 따라하며 배우는 C++
#pragma once vs. #ifndef
header guard로 #pragma once를 쓰는 방법과 #ifndef 쓰는 방법 두개를 설명해주셨는데, 두 개의 차이점이 있을까요?구글링해보면 #pragma once가 처리속도가 빠르지만, 지원되지 않는 compiler가 있는 것 같고 (현재는 대부분의 compiler는 지원되지만), #ifndef 는 모든 compiler에서 지원되지만 처리속도가 #pragma once에 비해서 느리다 라는 것 같은데, 맞는 내용인지 모르겠네요.
- 미해결홍정모의 따라하며 배우는 C++
쓰레드 이동 생성자 질문
#include<iostream> #include<future> #include<thread> using namespace std; int main() { { std::promise<int> prom;//future를 받아주는 존재가 필요해서 promise 거침 auto fut = prom.get_future(); auto t = std::thread([](std::promise<int>&& prom) { this_thread::sleep_for(chrono::milliseconds(1000)); prom.set_value(1 + 2); }, std::move(prom));//prom소유권을 넘겨받음 cout << "before get" << endl; cout << fut.get() << endl;//prom이 setvalue되어 값을 받아오도록 fut은 계속 기다림 cout << "after get" << endl; t.join();//thread끝나는 걸 기다려줌 } }위 코드를 전 아래처럼 이해했습니다futre가 promise의 future를 공유 받음 쓰레드 생성되며 promise의 소유권을 받음(여전히 future와 공유 관계)fut가 prom의 setvalue까지 기다림prom의 setvalue후 fut 출력됨쓰레드 join쓰레드에 std::move의 존재 이유가 궁금해서 알아보니, 쓰레드의 이동생성자였습니다. 그래서 prom의 소유권이 쓰레드로 가는건가 궁금합니다. 쓰레드 생성 후 prom.set_value(1)을 해보니 에러가 뜨기도 했습니다.
- 미해결홍정모의 따라하며 배우는 C++
코드 실행속도가 너무 느립니다.
강의를 보고 따라한 아래 코드의 실행속도가 강사님에 비해 너무나 느립니다. 실행환경의 문제인가요??#include<iostream> #include<thread> #include<atomic>//나눌 수 없다는 뜻. 쓰레드에서 연산이 한번에 이루어지도록 함 #include<mutex> #include<chrono> using namespace std; mutex mtx; int main() { //atomic<int> shared_memory(0); int shared_memory(0); auto count_func = [&]() { for (int i = 0; i < 1000; ++i) { //cout << shared_memory << endl; this_thread::sleep_for(chrono::milliseconds(1)); //doSomething; //mtx.lock(); //std::lock_guard lock(mtx);//unlock필요없음 std::scoped_lock lock(mtx); shared_memory++; //shared_memory.fetch_add(1); //mtx.unlock(); //shared memory의 값을 더할 떄의 과정 //1.shared memory값을 cpu로 가져옴 //2.1더함 //3.sharedmemory에 결과 저장 //값을 읽어들었을 때, 값이 바뀌면 더하기가 씹혀버림 => 잘못된 결과 //해결법 //1. atomic 사용 //2. fetchadd //3. mutex lock } }; thread t1 = thread(count_func); thread t2 = thread(count_func); t1.join(); t2.join(); std::cout << "After" << endl; std:: cout << shared_memory << endl; return 0; }
- 미해결홍정모의 따라하며 배우는 C++
맥 "clang: error: linker command failed with exit code 1 " 에러
안녕하세요 맥 사용자 입니다. 답변으로 아래와 같이 추가 질문 드립니다.
- 미해결홍정모의 따라하며 배우는 C++
맥 "clang: error: linker command failed with exit code 1 " 에러
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! 안녕하세요 맥 사용자입니다.본 강의 챕터 관련하여 궁금한 점이 있어 글을 남깁니다.커뮤니티에서 "lahat"님의 문제와 답변을 참고 삼아 clang+ add.cpp main_chapter1_11.cpp로 링킹 하였으나, main_chapter1_11.cpp파일이 "clang: error: linker command failed with exit code 1 "와 같은 오류 메세지를 띄고 있고 a.out 프로그램은 실행은 정상적으로 실행이 됩니다. 여기서 궁금한 점은 링킹을 정상적으로 성공 후에도 main.cpp에서는 위와 같은 오류 메세지를 띄고 있는 지 궁금합니다. 바쁘신 와중에 긴 글을 읽어주셔서 감사합니다.
- 미해결홍정모의 따라하며 배우는 C++
#include <algorithm>을 해주는 이유
16.3에서 설명해주신 코드에서#include <algorithm>을 해주지 않아도 min_element()나 sort(), reverse()가 정상적으로 작동이 되는데, 그 이유가 궁금합니다! #include <iostream> #include <vector> using namespace std; int main() { vector <int> container; for(int i = 0; i < 10; ++i) container.push_back(i); auto itr = min_element(container.begin(), container.end()); cout << *itr << endl; // 삽입 itr = find(container.begin(), container.end(), 3); container.insert(itr, 128); for (auto &e : container) cout << e << " "; cout << endl; // 정렬 sort(container.begin(), container.end()); for (auto &e : container) cout << e << " "; cout << endl; // reverse 정렬 reverse(container.begin(), container.end()); for (auto &e : container) cout << e << " "; cout << endl; return 0; }
- 해결됨홍정모의 따라하며 배우는 C++
call by reference 시 퍼포먼스에 관한 질문입니다.
과제로 내주신 것 중 std::thread와 std::promise를 사용하는 것을 먼저 해보고 divide and conquer를 std::thread를 이용해서 구현하는 것을 해봤는데, 궁금증이 생겨서 질문드렸습니다.강의 영상 막바지에 보여주셨던 std::async와 std::future를 사용했던 예제를 참고해서, 하나의 변수에 여러 스레드가 값을 누적시키는 것이 아닌 각자의 local sum에 값을 누적시킨 후 마지막에 모두 더하는 방식으로 구현해봤습니다. // TODO #1 : use divide and conquer strategy for std::thread cout << "thread" << endl; { const auto sta = chrono::steady_clock::now(); unsigned long long sum = 0; vector<std::thread> threads; vector<unsigned> sums; threads.resize(n_threads); sums.resize(n_threads); const unsigned n_per_thread = n_data / n_threads; for (unsigned t = 0; t < n_threads; t++) { threads[t] = std::thread(dotProductThread, std::ref(v0), std::ref(v1), t * n_per_thread, (t + 1) * n_per_thread, std::ref(sums[t])); } for (unsigned t = 0; t < n_threads; t++) { threads[t].join(); sum += sums[t]; } const chrono::duration<double> dur = chrono::steady_clock::now() - sta; cout << dur.count() << endl; cout << sum << endl; cout << endl; }그리고 처음에는 std::thread가 사용할 함수인 dotProductThread의 구현을 call by reference를 반환값처럼 사용하도록 아래와 같이 구현했습니다.auto dotProductThread(const vector<int>& v0, const vector<int>& v1, const unsigned i_start, const unsigned i_end, unsigned& local_sum) { for (unsigned i = i_start; i < i_end; i++) { local_sum += v0[i] * v1[i]; } }그런데 실행해봤더니 정답은 제대로 나오지만 속도가 제가 구현한 std::thread와 std::promise를 사용한 예제보다 훨씬 느렸고, 심지어 std::innerproduct보다도 느렸습니다.뭐가 문제일까 싶어 여러가지를 바꿔보다가 아래와 같이 dotProductThread함수에서 매번 레퍼런스에 값을 더하지 않고 변수를 하나 선언해 누적하다가 마지막에만 넘겨주도록 하였습니다.auto dotProductThread(const vector<int>& v0, const vector<int>& v1, const unsigned i_start, const unsigned i_end, unsigned& local_sum) { unsigned t = 0; for (unsigned i = i_start; i < i_end; i++) { t += v0[i] * v1[i]; } local_sum = t; }실행했더니 속도가 std::thread와 std::promise를 사용한 예제와 거의 비슷하게 나와주었습니다.call by reference로 전달된 참조에 너무 빈번하게 접근해도 퍼포먼스 저하가 일어난다고 봐도 될까요?그리고 시험삼아 출력문을 dotProductThread 내에 작성해봤더니 race condition은 일어나지 않는 것 같았습니다. 이런 경우 굳이 std::atomic이나 뮤텍스를 사용할 필요는 없나요? 또는 작업이 더욱 복잡해진다면 안정성을 위해 사용해줘야 하는 걸까요?(프로그래머가 미처 고려하지 못한 상황이라거나)
- 해결됨홍정모의 따라하며 배우는 C++
15.1 소유권 이동 관련 질문
15.1 강의에서 16분 20초 부근에AutoPtr(AutoPtr &a) { m_ptr = a.m_ptr; // 이 부분 a.m_ptr = nullptr; // 이 부분 } AutoPtr& operator = (AutoPtr &a) { if (&a == this) return *this; delete m_ptr; m_ptr = a.m_ptr; // 이 부분 a.m_ptr = nullptr; // 이 부분 return *this; }소유권 이동을 해주기 위해 AutoPtr 클래스에 위와 같이 복사생성자와 =연산자 오버로딩을 해준다고 하셨습니다.그런데 이 때, 제가 "이 부분"이라고 주석처리 해놓은 부분을 보면 같은 명령을 수행하도록 되어있습니다. 왜 이렇게 두 번 해주는지 궁금합니다. 복사생성자에서 해주는 것과 연산자 오버로딩에서 해주는 것. 둘의 차이는 무엇인가요? 그리고 =연산자 오버로딩에서 return *this를 하는 이유도 궁금합니다.
- 미해결홍정모의 따라하며 배우는 C++
const와 extern
안녕하세요const가 변수의 외부연결을 막는 것 같은 상황이 생기는 거 같아 이렇게 여쭤봅니다. 파일구조는 vars.cpp -> header.h -> main.cpp&test.cpp입니다.vars.cppheader.hmain.cpptest.cpp의도한대로 잘 작동하며 출력화면은 아래와 같습니다.그런데 여기서 vars.cpp에서 nmsp_a변수를 int에서 const int형으로 바꾸고,header.h에서도 nmsp_a를 extern int에서 extern const int형으로 바꾸고 돌려보면아래와 같이 오류가 발생합니다.차이점은 equipe namespace안의 int nmsp_a변수를 그냥 int에서 const int로 바꾼 것 뿐인데 충돌이 일어나는 것처럼 보입니다.const와의 어떠한 문제 때문인 것으로 추측되는데 vars.cpp의 namespace안의 nmsp_a변수에는 extern을 붙이지 않아왔고 nmsp_a를 가져다끌어 쓰는 header.h에서만 extern을 붙여줬는데 아래 사진과 같이vars.cpp의 nmsp_a 변수에 오류를 발생시키던 const를 붙이되 extern또한 추가로 붙여주면 정상출력을 합니다. const를 안 붙이는 상황에선,변수를 정의해두는 vars.cpp에서는 extern를 쓰지않고이를 가져오는 주체인 header.h에만 extern를 붙여도 정상작동했지만 const를 붙이는 상황에선,vars.cpp, header.h 두 곳 모두 각각 변수에 extern을 붙여줘야한다는 결론을 얻었습니다. 말이 좀 복잡한데 정리하자면왜 변수에 const가 없으면vars.cpp에는 extern을 안 붙여도 되고왜 변수에 const가 있으면vars.cpp에도 extern을 꼭 달아줘야하는지그런 차이가 왜 생기는지 궁금합니다. 감사합니다.