2013-09-03 2 views
0

std :: tr1 :: shared_ptr을 사용하기 시작했으며 지금까지 아주 좋아합니다. 함정 중 일부 (예 : 스마트 포인터 멤버가 서로 포함 된 두 개의 클래스)를 이해합니다. 하지만 스마트 포인터를 사용할지 여부를 확신 할 수없는 다른 경우가 있습니다.std :: tr1 :: shared_ptr 벡터 다루기 규칙

예.

class Scene; 
typedef shared_ptr<Scene> ScenePtr; 

Class SceneManager { 
public: 

    int size() { return _scenes.size(); } 
    ScenePtr scene(int i) { return _scenes[i]; } 

private: 
    vector<ScenePtr> _scenes; 
} 

이것은 모두 훌륭하고 잘 작동합니다. 내가 외부 컨트롤러가있는 경우에는, 일을 어떤 단점이있다 :

여기
for(int i=0; i<_sceneManager->size(); i++) { 
    ScenePtr scene = _sceneManager->scene(i); 
    scene->doSomething(); 
} 

'장면'분명히 각 ScenePtr의 참조 카운트를 증가하지만,이 범위를 벗어나면 다음 다시 감소합니다. 그러나 성능 (또는 기타) 단점이 있습니까?

는 또한 나는 보통의 C 포인터

for(int i=0; i<_sceneManager->size(); i++) { 
    Scene* scene = _sceneManager->scene(i).get(); 
    scene->doSomething(); 
} 

를 사용할 수 있습니다 그러나 이것은 더 나은 실제로? 또는 동일합니까? 참조 횟수가 증가합니까? (함수 호출시), 첫 번째 줄을 떠나 자마자 줄었습니까?

나는 종종 참조를 사용하는 데 어떤 합병증이 있습니까?

for(int i=0; i<_sceneManager->size(); i++) { 
    Scene& scene = *_sceneManager->scene(i); 
    scene.doSomething(); 
} 

그리고 마지막으로는, 심지어는 전혀 ScenePtr을 반환하는 것이 좋습니다, 또는 씬 매니저 :: 장면 (i)는 A (장면 *) 또는 (장면 &)을 반환해야합니까?

마찬가지로, 자주 사용하는 순서가 지정된지도를 만들려면 다음을 사용합니다. vector _scenesArray; 지도 _scenes지도;

개체에 이름이나 순서대로 액세스 할 수 있습니다. std :: tr1 :: shared_ptr를 사용하면 둘 다 ScenePtr이되어야합니까? 또는 그 중 하나 ScenePtr과 다른 하나 Scene *?

+3

"tr1 :: shared_ptr"을 (를) 사용하고 있습니까? 아니면'std :: shared_ptr'가'tr1' 네임 스페이스에 정의되어있는 Visual Studio를 사용하고 있습니까? –

+1

'SceneManager :: scene'은'SceneManager'를 리턴해야한다고 생각합니다. 왜냐하면'SceneManager'와'(get) scene'은 내가 처리 할 리소스가'Scene'이라는 것을 암시하기 때문입니다. – GManNickG

+0

그리고 GMan의 생각에 뒤이어,'scene()'이 참조 *를 직접적으로 돌려주는 지에 대해서 편집증이있는 참조 카운트를 스켈치합니다. 매달려있는 참조를 사용하지 않도록하기 위해 그것까지 달려 있지만, 이것이 고수하기가 어려울 것 같지 않습니다. – WhozCraig

답변

0

모두 사용 사례에 따라 다릅니다.

포인터 또는 참조를 사용하면 의심되는만큼 참조 계산 오버 헤드가 절약됩니다.

...하지만 ... 종종 오버 헤드는 걱정 할만큼 중요하지 않습니다과 :

sceneManager은 여러 스레드에서 사용하거나 함수는하지만 접근의 안전을 안전 reenterent해야 할 경우 공유 포인터가 선호 될 수 있습니다. shared_ptr을 사용하지 않는 경우에는 객체가 파기되지 않도록해야합니다.

반환 할 대상은 개체의 소유권이 전달되는지 여부에 따라 다릅니다. 오브젝트가 이미 다른 곳에 공유 포인터에 있으면 shared_ptr에 대한 포인터로 이동해서는 안됩니다. shared_ptr에서 shared_ptr로 전달해야하거나 shared_ptrs의 각 체인이 객체 삭제를 시도합니다. 다중 삭제 => 충돌.

소유권이 SceneManager으로 유지되는 경우 참조를 반환하면 개체를 쉽게 사용할 수 있고 소유권을 명확하게 표현할 수 있습니다.마찬가지로

, 내가 자주 사용하는 데 사용되는 명령지도해야 할 일 : 벡터 _scenesArray을; 지도 _scenes지도;

간결함과 유연성을 위해 나는 shared_ptrs를 모두 가지고 시작할 것입니다. 나중에 응용 프로그램에서 병 목으로 판별 될 가능성이 희박한 상황에서 성능 최적화로 논리를 추가하고 추가 할 수 있습니다.

관련 문제