2017-12-31 21 views
0

두 가지 질문이 있습니다.C++의 const 값에 대한 const 포인터 이해

우선 const 값에 대한 const 포인터를 이해하는 데 약간의 문제가 있습니다. C::insert은 컴파일러 오류가 발생하는 반면 나는 B::insert이 작동하는 이유를 알지 못합니다. 나는 C의 목록이 C::insert의 매개 변수와 정확하게 일치하지 않는다는 것을 의미합니까?

내 두 번째 질문은 A const * const a인지 여부도 const A& a 일 수 있습니다.

class A 
{ 
    //Do stuff 
}; 

class B 
{ 
private: 
    list<A const *> l; 

public: 
    void insert(A const * const a) 
    { 
     l.push_back(a); 
    } 
}; 

class C 
{ 
private: 
    list<A const * const> l; 

public: 
    void insert(A const * const a) 
    { 
      l.push_back(a); 
    } 
}; 

편집 (컴파일 오류) : 당신의 선언 A const * const에서

g++ -Wall -c -O2 "sonnensystem.cpp" -std=c++11 (im Verzeichnis: C:\Users\Kenan\Desktop\OPR\cppcode\Konzepte\Kapselung\Architektur\sonnensystem01) 
In file included from C:/TDM-GCC-64/lib/gcc/x86_64-w64-mingw32/5.1.0/include/c++/x86_64-w64-mingw32/bits/c++allocator.h:33:0, 
      from C:/TDM-GCC-64/lib/gcc/x86_64-w64-mingw32/5.1.0/include/c++/bits/allocator.h:46, 
      from C:/TDM-GCC-64/lib/gcc/x86_64-w64-mingw32/5.1.0/include/c++/string:41, 
      from C:/TDM-GCC-64/lib/gcc/x86_64-w64-mingw32/5.1.0/include/c++/bits/locale_classes.h:40, 
      from C:/TDM-GCC-64/lib/gcc/x86_64-w64-mingw32/5.1.0/include/c++/bits/ios_base.h:41, 
      from C:/TDM-GCC-64/lib/gcc/x86_64-w64-mingw32/5.1.0/include/c++/ios:42, 
      from C:/TDM-GCC-64/lib/gcc/x86_64-w64-mingw32/5.1.0/include/c++/ostream:38, 
      from C:/TDM-GCC-64/lib/gcc/x86_64-w64-mingw32/5.1.0/include/c++/iostream:39, 
      from sonnensystem.cpp:1: 
C:/TDM-GCC-64/lib/gcc/x86_64-w64-mingw32/5.1.0/include/c++/ext/new_allocator.h: In instantiation of 'struct __gnu_cxx::new_allocator<const A* const>': 
C:/TDM-GCC-64/lib/gcc/x86_64-w64-mingw32/5.1.0/include/c++/bits/allocator.h:92:11: required from 'class std::allocator<const A* const>' 
C:/TDM-GCC-64/lib/gcc/x86_64-w64-mingw32/5.1.0/include/c++/bits/stl_list.h:315:9: required from 'class std::__cxx11::_List_base<const A* const, std::allocator<const A* const> >' 
C:/TDM-GCC-64/lib/gcc/x86_64-w64-mingw32/5.1.0/include/c++/bits/stl_list.h:507:11: required from 'class std::__cxx11::list<const A* const>' 
sonnensystem.cpp:28:27: required from here 
C:/TDM-GCC-64/lib/gcc/x86_64-w64-mingw32/5.1.0/include/c++/ext/new_allocator.h:93:7: error: 'const _Tp* __gnu_cxx::new_allocator<_Tp>::address(__gnu_cxx::new_allocator<_Tp>::const_reference) const [with _Tp = const A* const; __gnu_cxx::new_allocator<_Tp>::const_pointer = const A* const*; __gnu_cxx::new_allocator<_Tp>::const_reference = const A* const&]' cannot be overloaded 
     address(const_reference __x) const _GLIBCXX_NOEXCEPT 
    ^
C:/TDM-GCC-64/lib/gcc/x86_64-w64-mingw32/5.1.0/include/c++/ext/new_allocator.h:89:7: error: with '_Tp* __gnu_cxx::new_allocator<_Tp>::address(__gnu_cxx::new_allocator<_Tp>::reference) const [with _Tp = const A* const; __gnu_cxx::new_allocator<_Tp>::pointer = const A* const*; __gnu_cxx::new_allocator<_Tp>::reference = const A* const&]' 
     address(reference __x) const _GLIBCXX_NOEXCEPT 
    ^
Kompilierung fehlgeschlagen. 
+0

컴파일러 오류를 포함 할 경우 유용합니다. 제 컴파일러에 오류가 없습니다. – Eljay

+0

@ 엘리제 내 편집을 참조하십시오. 나는 또한이 온라인 컴파일러 [link] (http://cpp.sh/)를 시험해 보았다. 거기서도 작동하지 않았습니다 :/ –

+0

[C++ 11에서'vector '?]을 허용합니까 (https://stackoverflow.com/questions/6954906/does-c11-allow-vectorconst-t)를 참조하십시오. 컴파일러는 '주소'에 대해 불평합니다. –

답변

3

, 첫 const는 말한다 변경할 수없는 값으로 A * 포인터 점 (A 가리키는 const 포인터). 두 번째 constconst int을 변경할 수없는 것처럼 해당 포인터의 값을 변경할 수 없다고 말합니다. list (및 다른 표준 컨테이너)은 멤버를 지정해야하므로 const 값일 수 없습니다.

두 번째 질문의 경우 사용 방법이 다르므로 A const * constconst A&은 비슷하지만 상호 교환 할 수 없습니다.

+0

고마워, 지금은 알아 냈어. 왜 정확하게 CopyAssignable이되어야 할까? –

+0

짧은 대답 : 언어가 필요하다고 말하기 때문입니다. 더 긴 대답 : 컨테이너가 복사, 생성, 크기 조정 등으로 요소가 이동되고 복사되므로 컨테이너의 기존 값을 업데이트 (복사를 통해 할당) 할 수 있어야합니다. – 1201ProgramAlarm

+0

도와 주셔서 감사합니다 :) @ SoronelHaetir 님의 의견이 맞나요? 그쵸?나는 시도했지만 작동하지 않는 것 같아요/그의 대답이 맞는지 여부를 알기 전에이 스레드를 닫고 싶지는 않습니다 : D –

1

std::list<T>을 사용할 때 T에 대한 요구 사항 중 하나는 CopyAssignable입니다. http://en.cppreference.com/w/cpp/container/list을 참조하십시오.

const 형식을 매개 변수로 사용하면 해당 요구 사항이 충족되지 않습니다. 하지 동일한 오류 경우 사용하는 경우, 유사한 오류가 발생합니다 : 어쨌든

std::list<const int> a; 
a.push_back(10); 

,

list<A const * const> l; 

는 사용할 수 없습니다.

0

A const * constA const & 사이의 유일한 차이점은 (널에게 A 참조를 얻을, if(!a) 가서 그냥 쉽게 역 참조 다음 A에 NUL 포인터를 캐스팅 수 있고) 포인터가 유효하지 않음을 확인하기가 쉽습니다이다 .

C::insert 경우는 내부 노드 값에 할당하려고하는 코드 때문입니다. push_back 대신 emplace_back을 사용하면 효과가있을 것입니다.

+0

push_back 대신 emplace_back을 사용하려고했지만 작동하지 않았습니다. 나는 여기에 이미 언급 된 다른 사람들처럼 일반적인 주장은 CopyAssignable 일 필요가 있다고 생각한다. –