2017-04-26 4 views
0

나는 다음과 같은 클래스 구조가 있습니다공유 포인터

클래스 Initialiser에서
class Bar { 
private: 
    std::shared_ptr<std::vector<int>> y_; 
public: 
    Bar(std::shared_ptr<std::vector<int>> p): 
     y_(p) 
    {} 

    int getFirstVal() {return y_->at(0);}; 
}; 

class Initialiser { 
private: 
    std::vector<int> x_; 
    Bar bar_; 
public: 
    Initialiser(std::vector<int>& v): 
     x_(v), 
     bar_(std::make_shared<std::vector<int>>(x_)) 
    {} 

    void set_x(std::vector<int> x) {x_ = x;} 

    void check(std::vector<int> x){ 
     set_x(x); 
     std::cout << "New value of x= " << bar_.getFirstVal() << std::endl; 
    } 
}; 



int main(){ 

    std::vector<int> z = {1,2,3}; 
    Initialiser init(z); 

    std::vector<int> x_new = {4,5,6}; 
    init.check(x_new); // should print 4 



} 

, 내가 같은 개인 회원에게 INT의 벡터와 클래스 바의 인스턴스를 가지고 있습니다. 막대는 int의 벡터에 대한 공유 포인터로 초기화되어야하며이 벡터는 Initialiser와 Bar에서 공유되어야합니다. 그러나 현재 Initialiser가 x의 setter를 호출하면 바 내부의 벡터에는 영향을 미치지 않습니다. 나는 이것을 에서 확인합니다.. 왜 체크() 가치 4 인쇄하지만 여전히 값 1?

답변

4
Initialiser(std::vector<int>& v): 
    x_(v), 
    bar_(std::make_shared<std::vector<int>>(x_)) 
{} 

당신은 새로운 벡터와 점, 즉 X_의 사본 것을, shared_ptr을을 만들 수 있습니다. 당연히 하나를 수정해도 다른 하나는 영향을받지 않습니다.


그러나 바 객체가 Initialiser 개체의 일부이기 때문에

class Initialiser { 
private: 
    std::shared_ptr<std::vector<int>> x_; 
    Bar bar_; 
public: 
    Initialiser(std::vector<int>& v): 
     x_(std::make_shared<std::vector<int>>(v)), 
     bar_(x_) 
    {} 
}; 
가 정말 필요가 없습니다 :

직선 전달 솔루션은 Initialiser과 바 모두가 벡터에있는 shared_ptr를 유지하는 것입니다 전혀 스마트 포인터. Bar는 단순히 벡터에 대한 참조를 보유 할 수 있습니다. 평생 관리 문제는 bar_가 컨테이너의 수명보다 길어 지거나 컨테이너의 수명이 오래 지속되지 않기 때문에 발생하지 않습니다.

class Bar { 
private: 
    std::vector<int>& y_; 
public: 
    Bar(std::vector<int>& p): 
     y_(p) 
    {} 

    int getFirstVal() {return y_.at(0);}; 
}; 

class Initialiser { 
private: 
    std::vector<int> x_; 
    Bar bar_; 
public: 
    Initialiser(std::vector<int>& v): 
     x_(v), 
     bar_(x_) 
    {} 
}; 

그러나 x_ 및 bar_의 순서는 문제가되므로주의해야합니다. 멤버 변수의 생성 순서는 멤버 초기화 목록의 순서가 아닌 클래스 정의에서 나타나는 순서입니다. 순서가 바뀌면 bar_가 x_보다 먼저 생성되기 때문에 프로그램의 동작은 정의되지 않습니다.

이 올바른 정렬은 구성원이 초기화의 역순으로 파괴되므로 객체 파괴 중 x_이 bar_보다 오래 지속되지 않도록합니다.

+0

또한 손에있는 경우 'shared_ptr'이 필요하지 않으며 'Bar' 객체가'Initialiser '가 소유 한 벡터에 대한 포인터 또는 참조를 보유하는 것이 적절할 수 있음을 지적 할 가치가 있습니다. – Persixty

+1

@ DanAllen - 예, 방금 추가하는 중이었습니다. 감사합니다 :) – StoryTeller

+0

도와 줘서 고마워! 이것은 좋은 해결책입니다. – beginneR

관련 문제