简体   繁体   中英

C++ shared_ptr manipulation logic

I have this logic:

struct Foo;
struct Bar;  

struct IComponent {
    virtual Foo * GetFoo() { return nullptr; }
    virtual Bar * GetBar() { return nullptr; }
}

struct Foo : public IComponent {
    Foo * GetFoo() override { return this; }
}

struct Bar : public IComponent {
    Bar * GetBar() override { return this; }
}

The components are managed by

class SimpleObject {
  public:
     void Add(IComponent * b){
        components.push_back(b);
        if (b->GetFoo()) foo = b->GetFoo();
     }

     template <typename T>
     T * GetComponent() const {
        for (size_t i = 0; i < components.size(); i++){
           if (T * tmp = dynamic_cast<T *>(components[i])){
            return tmp;
           }
        }
        return nullptr;
     }
   
  private:
    Foo * foo;
    std::vector<IComponent *> components;
}


template <> Foo * SimpleObject::GetComponent<Foo>() const { 
    return this->foo; 
}

I can have multiple different SimpleObject . However, each of them can contain same or different components (one component can be assigned to multiple SimpleObject ). GetComponent is used to only access the associated component. There should be no ownership transfer (however, I dont know how to force this since a library user can, of course incorrectly or my mistake, do this) - components are not aware of each other, only via the SimpleObject they are asociated to.

Now, I dont like the raw pointers. I converted std::vector<IComponent*> to std::vector<std::shared_ptr<IComponent>> and void Add(IComponent* b) to void Add(std::shared_ptr<IComponent> b) .

However, I am not sure how to manage GetComponent method. Should I also convert its return type to shared_ptr or is it better to stick with the raw pointer and return it via .get() ? The same goes for helper variable foo . However, in this case, I think that keeping it as a raw pointer is better.

If you don't want to expose ownership (let alone transfer it) as part of your interface, returning a raw pointer (or some special observer pointer type, if you use such) is plainly the right idea. (In particular, avoid constructions like const std::shared_ptr<T>& foo() that meaninglessly express observation in terms of some ownership elsewhere .) This approach also saves a bit of reference count fiddling and is compatible with your explicit specialization.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM