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();
}
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.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
consideringBehaviourProcessor
is not a base class. This may be an unnecessary pessimisation. I recommend considering a value member:Likewise, the getters and setters seem to be largely redundant. The classes could be much simpler as aggregates.