0

I'll start by posting the code i currently have. I tried to reduce it as much as possible but since i'm not so experienced with C++ i don't know if i may have left out to much or just showing to much code.

class IBehavior {
public:
  virtual void DoIt() = 0;
};

class BehaviorA : public IBehavior {
  void DoIt() {
      cout << "Behavior: A\n";
  };
};

class BaseOfAB {
  IBehavior behavior;

  void DoIt() {
      behavior.DoIt();
  };
};

class A : public BaseOfAB {
  A() {
    BehaviorA behavior;   
  };  
};

int main()
{
    A objA;
    objA.DoIt();

    return 0;
}

What i'm trying to do is define the property of its behavior in a class that implements the abstract class. Then i want class BaseOfAB to have an object which will be declared in the subclass. And by doing so the behavior.DoIt() should have the behavior that is implemented in the class BehaviorA. Does anyone know how to do this cause i can't seem to figure it out?

Thanks in advance.

Kind regards,

Bob

Bob
  • 149
  • 1
  • 1
  • 7
  • 2
    For polyrphism to work you need a *pointer* or a *reference* to the concrete object (expressed through the base class, e.g. `IBehavior*`). And you need to override the actual pure virtual function, not some other unrelated function. Please get [a few good books](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list/388282#388282) to read about this (which you need to read anyway, since you make some very basic mistakes in regards to classes, inheritance and members in general). – Some programmer dude Apr 22 '18 at 16:01
  • I don't understand the question, but this code won't work, because you try to create an object of an abstract class (`BaseOfAB::behavior`). – Christian Hackl Apr 22 '18 at 16:02
  • @Someprogrammerdude : Could you explain what i'm doing wrong in this case? I will have a look at some good books. What do you mean by override the actual pure virtual function? Is that not what i'm doing? – Bob Apr 22 '18 at 16:09
  • Sorry that is true, going to edit it now. – Bob Apr 22 '18 at 16:11
  • Do you need to be able to change the behavior of a subclass at runtime or is it fixed at compile time? As in, will `A` always use `BehaviorA`? – Chris Drew Apr 22 '18 at 16:19
  • Thats what i was getting to later. But yes i also want to implement a function SetBehavior. But i have no idea on how to get this done. So if you could help me out with that, that would be great! Still in both cases i would like to know how and why. – Bob Apr 22 '18 at 16:29

1 Answers1

0

To implement polymorphism in C++ you need a pointer or reference to a base class. As BaseOfAB will own this polymorphic object you can't use a reference but will have to use a pointer. Preferably a smart-pointer so you don't have to worry about manual memory management. The interface IBehavior will have to have a virtual destructor so that if you delete a pointer to an IBehavior it will correctly delete the derived class.

I've chosen std::unique_ptr as it is the most light-weight smart-pointer in C++ although you need some understanding of C++ move-semantics to work with it.

#include <iostream>
#include <memory>

class IBehavior {
public:
  virtual void DoIt() = 0;
  virtual ~IBehavior() = default;
};

class BehaviorA : public IBehavior {
public:
  void DoIt() override { std::cout << "Behavior: A\n"; }
};

class BaseOfAB {
  std::unique_ptr<IBehavior> behavior;
public:
  BaseOfAB(std::unique_ptr<IBehavior> behavior) : behavior(std::move(behavior)) {}
  void SetBehavior(std::unique_ptr<IBehavior> newBehavior) {
    behavior = std::move(newBehavior);
  }
  void DoIt() { behavior->DoIt(); };
};

class A : public BaseOfAB {
public:
  A() : BaseOfAB(std::make_unique<BehaviorA>()) {}  
};

int main() {
    A obj;
    obj.DoIt();
    obj.SetBehavior(std::make_unique<BehaviorB>());
    obj.DoIt();
}

Live demo.

The use of the smart-pointer std::unique_ptr ensures that the IBehavior instance is deleted correctly when the BaseOfAB instance is deleted or when it is replaced in SetBehavior. It also provides reasonable default behavior for copy/move constructor and copy/move assignment.

Chris Drew
  • 14,926
  • 3
  • 34
  • 54
  • Thank you for your help it is very much appreciated. Could you give me some explanation about what is going on with those smart pointers? I did get something about that in a course but not in detail. The virtual destructor, if i'm correct is to make sure that upon deletion it will attempt to delete it as the derived object and not as the base class? – Bob Apr 22 '18 at 17:09
  • @SSJVegetto I've added a little explanation but I think an in-depth explanation of smart pointers is beyond the scope of this answer and I suggest you [read elsewhere](https://stackoverflow.com/q/106508/3422652). – Chris Drew Apr 22 '18 at 17:30
  • @SSJVegetto Yes, you are correct about the virtual destructor. And if there is anything specific about the use of `std::unique_ptr` you don't understand feel free to ask. – Chris Drew Apr 22 '18 at 18:01