简体   繁体   中英

Can someone please tell me if I'm using unique pointers correctly

I'm trying to use smart pointers more but am not sure if I'm using them correctly. I seem to need to use std::move all over the place. Don't quite understand why, but it's working. What my example code does isn't important (nothing as happens:)), I'm more concerned with the structure of how i'm using these pointers. Thanks for any advice.

class IBehaviour {
public: virtual void Process() = 0;
};

class BehaviourA : public IBehaviour {
    public: virtual void Process() override { /* do behaviour A stuff */ }
};

class BehaviourB : public IBehaviour {
    public: virtual void Process() override {/* do behaviour B stuff */ }
};

class BehaviourC : public IBehaviour {
    public: virtual void Process() override {/* do behaviour C stuff */ }
};

class BehaviourProcessor {
public:
    BehaviourProcessor(int m) {
        if (m == 1)     behaviour = std::make_unique<BehaviourA>();
        else if (m==2)  behaviour = std::make_unique<BehaviourB>();
        else            behaviour = std::make_unique<BehaviourC>();
    }

    std::unique_ptr<IBehaviour> getBehaviour() {
        return std::move(behaviour);
    }

    std::unique_ptr<IBehaviour> behaviour = nullptr;
};

class Container {
public:
    void setProcessor(std::unique_ptr<BehaviourProcessor> ada) {
        adaproc = std::move(ada);
    }

    std::unique_ptr<BehaviourProcessor> getProcessor() {
        return std::move(adaproc);
    }

    std::unique_ptr<BehaviourProcessor> adaproc = nullptr;
};

int main()
{
    Container c;
    std::unique_ptr<BehaviourProcessor> beh = std::make_unique<BehaviourProcessor>(1);
    c.setProcessor(std::move(beh));
    c.getProcessor()->getBehaviour()->Process();

    beh = std::make_unique<BehaviourProcessor>(2);
    c.setProcessor(std::move(beh));
    c.getProcessor()->getBehaviour()->Process();

    beh = std::make_unique<BehaviourProcessor>(3);
    c.setProcessor(std::move(beh));
    c.getProcessor()->getBehaviour()->Process();
}
class IBehaviour { public: virtual void Process() = 0; }; std::unique_ptr<IBehaviour> behaviour = nullptr; behaviour = std::make_unique<BehaviourA>();

This is wrong. By pointing the smart pointer to a base sub object, it will delete through that base pointer, which will result in undefined behaviour because the destructor of the base isn't virtual. Solution: declare ~IBehaviour virtual.


 std::unique_ptr<IBehaviour> getBehaviour() { return std::move(behaviour); } std::unique_ptr<BehaviourProcessor> getProcessor() { return std::move(adaproc); }

These are dubious. A non-rvalue-ref-qualified function should not move from a member. This will probably not be expected by the caller.


It's unclear why you use dynamic allocation for Container::adaproc considering BehaviourProcessor is not a base class. This may be an unnecessary pessimisation. I recommend considering a value member:

class Container {
public:
    BehaviourProcessor adaproc;

Likewise, the getters and setters seem to be largely redundant. The classes could be much simpler as aggregates.

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