`const shared_ptr <T>`와`shared_ptr <const T>`의 차이점은 무엇입니까?


115

다음과 같은 C ++의 공유 포인터에 대한 접근 자 메서드를 작성하고 있습니다.

class Foo {
public:
    return_type getBar() const {
        return m_bar;
    }

private:
    boost::shared_ptr<Bar> m_bar;
}

따라서 getBar()반환 유형 의 const-ness를 지원 boost::shared_ptr하려면 Barit이 가리키는 수정을 방지 해야합니다 . 내 생각 엔 그것이 shared_ptr<const Bar>내가 그것을하기 위해 돌아가고 싶은 타입이다. 반면 const shared_ptr<Bar>에 포인터 자체가 다른 것을 가리 키도록 재 할당 하는 것을 막지 BarBar그것이 가리키는 것을 수정할 수있게 한다 ... 그러나 나는 확실하지 않다. 확실히 아는 사람이 이것을 확인하거나 내가 틀렸다면 나를 바로 잡을 수 있다면 감사하겠습니다. 감사!


3
정확히 당신이 말한 것입니다. 당신은 사업자에 대한 문서를 볼 수 있습니다 *->이를 확인 할 수 있습니다.
syam

2
T *const과 의 차이점은 무엇입니까 T const *? 똑같다.

3
@ H2CO3 전혀. 는 const일반적으로 _precedes를 수정하므로 T *const에 대한 const포인터 TT const*에 대한 포인터 const T입니다. 그리고 const앞에 아무것도 사용 하지 않는 것이 가장 좋습니다 .
James Kanze

6
H2CO3의 포인트입니다 @JamesKanze : 차이 T *const와는 T const *차이와 같습니다 const shared_ptr<T>shared_ptr<const T>
조나단 Wakely

1
@JamesKanze 아, 그래. T *constnon-const에 대한 const 포인터 T이므로 const shared_ptr<T>. 반대로 T const *는에 대한 상수가 아닌 포인터 const T이므로 shared_ptr<const T>.

답변:


176

당신이 옳습니다. shared_ptr<const T> p;유사하다 const T * p;(등가 또는 T const * p;), 즉, 뾰족한 인 const반면 const shared_ptr<T> p;비슷 T* const p;하는 수단 p이다 const. 요약해서 말하자면:

shared_ptr<T> p;             ---> T * p;                                    : nothing is const
const shared_ptr<T> p;       ---> T * const p;                              : p is const
shared_ptr<const T> p;       ---> const T * p;       <=> T const * p;       : *p is const
const shared_ptr<const T> p; ---> const T * const p; <=> T const * const p; : p and *p are const.

동일에 대한 보유 weak_ptrunique_ptr.


1
또한 정규 포인터 (const T * vs. T * const vs. T const *)에 대해 내 머릿속에있는 질문에 대답했습니다. :) 나는 SO에 대한 나의 질문이 너무 광범위 하기를 원하지 않았기 때문에 언급하지 않았으며 이것은 나의 현재 작업과 관련된 질문이었습니다. 어쨌든 지금은 잘 이해하고있는 것 같아요. 감사!
Dave Lillethun jul.

9
도움이되어 다행입니다. const T* p;', 'T const * p;및 에 대해 기억하기 위해 사용하는 마지막 팁입니다 T * const p. 의 동일한면에있는 것이 무엇 *인지 의미에서 구분자로를 참조하십시오 . const*
Cassio Neri

5
내 경험 법칙은 const항상 왼쪽에있는 것을 의미합니다. 왼쪽에 아무것도 없으면 오른쪽에있는 것입니다.
hochl

hochi-const T * p는 어떻습니까; T const * p ;?
Vlad

Cassio, 반환 된 유형 const shared_ptr <T>의 경우 const 포인터에는 해당되지 않지만 상수가 아닌 함수에서는 사용할 수 없다고 추가 할 수 있습니다.
Vlad

2

boost::shared_ptr<Bar const>Bar공유 포인터를 통한 개체 수정을 방지 합니다. 반환 값으로 const in boost::shared_ptr<Bar> const은 반환 된 임시 에서 상수 가 아닌 함수를 호출 할 수 없음 을 의미합니다. 실제 포인터 (예 Bar* const:) 인 경우 완전히 무시됩니다.

일반적으로 여기에서도 일반적인 규칙이 적용됩니다. const앞에 오는 것을 수정합니다. in boost::shared_ptr<Bar const>, the Bar; 에서는 boost::shared_ptr<Bar> const인스턴스화입니다 ( boost::shared_ptr<Bar>const.


1
@gatopeich 그래서 당신은 delete그것을 할 수 있습니다.
Marcin

@Marcin 당신은 ellaborate 수 있습니까?
gatopeich

1
#Check this simple code to understand... copy-paste the below code to check on any c++11 compiler

#include <memory>
using namespace std;

class A {
    public:
        int a = 5;
};

shared_ptr<A> f1() {
    const shared_ptr<A> sA(new A);
    shared_ptr<A> sA2(new A);
    sA = sA2; // compile-error
    return sA;
}

shared_ptr<A> f2() {
    shared_ptr<const A> sA(new A);
    sA->a = 4; // compile-error
    return sA;
}

int main(int argc, char** argv) {
    f1();
    f2();
    return 0;
}

std::make_shared()(C ++ 14 이후) 의 사용을 제안 할 수 있습니다 .
조엘 Bodenmann

0

@Cassio Neri의 답변을 기반으로 간단한 설명을 원합니다.

#include <memory>

int main(){
    std::shared_ptr<int> i = std::make_shared<int>(1);
    std::shared_ptr<int const> ci;

    // i = ci; // compile error
    ci = i;
    std::cout << *i << "\t" << *ci << std::endl; // both will be 1

    *i = 2;
    std::cout << *i << "\t" << *ci << std::endl; // both will be 2

    i = std::make_shared<int>(3);
    std::cout << *i << "\t" << *ci << std::endl; // only *i has changed

    // *ci = 20; // compile error
    ci = std::make_shared<int>(5);
    std::cout << *i << "\t" << *ci << std::endl; // only *ci has changed

}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.