At 9:20, it was really interesting that we didn't see any compile errors with the Vulkan class until the main method contained code to instantiate Vulkan.
Perhaps one motivation to have good unit tests so that's not a surprise later on :) Agreed this is perhaps one thing the compiler could sniff out early, and I bet there are some static analysis tools out there that can help.
Yes -- this is one of those C++ idioms where an interface (or base class in general) should have a virtual destructor. I have some videos on the playlist otherwise with further explanation here: ua-cam.com/video/XvzgC5WoBCE/v-deo.html
Hi Mike, Love the C++ series! I have a question that I'm having trouble finding the answer to. Is it bad practice to have an interface class but have the derived classes not fully implement the member functions? I have a settings classes that contains several member functions for every possible output (minValue,maxValue,settingName,value,listOfOptions(think drop down menu). But every setting needs these members. Ex: A toggle setting only needs value and settingName, not listOfOptions. I haven't gotten to your c++ design patterns, I'm not sure if its talked about there. Any help is greatly appreciated. Should a be avoid this design? The only way I know to add derived objects to a list would be to pass the based pointers to avoid object slicing.
Hard to say without seeing code, but sometimes a derived class may not implement all the behaviors of the base class. In practice that's why we fall back to the base classes behavior. If you have a true interface (lots of pure virtual functions) and many members are not implemented, that could be a sign that it's not the same type. You could consider the strategy pattern in your situation if you just need to configure behavior based on inputs
@@MikeShah wow thanks for such a quick response! I'll look into the stagety design pattern. Is this a question appropriate for your community forum? I could provide a more detailed explanation of what I'm trying to do along with code.
Hi Mike, thanks for the great explanation! I do have one question though. I swapped out your usage of a raw pointer for a unique_ptr and I added default constructors and destructors to IRenderer, OpenGL and Vulkan classes each with some std::cout statements for "constructing X", "destructing X". I notice that when creating a new instance of the child class the constructor of the base class is called, then the constructor of the child class but at the termination of scope only the base destructor is called and not the child destructor? Why is this? Does that mean I have a memory leak of the child class?
A little bit of a special thing that you have to do is make the destructor virtual for the base class to ensure both will get called -- give that a try :)
At 9:20, it was really interesting that we didn't see any compile errors with the Vulkan class until the main method contained code to instantiate Vulkan.
Perhaps one motivation to have good unit tests so that's not a surprise later on :) Agreed this is perhaps one thing the compiler could sniff out early, and I bet there are some static analysis tools out there that can help.
@@MikeShah I'm so encouraged you say this. Haha I was thinking this right after I posted.
Great video. Very well explained. Thank you.
Cheers, thank you for the kind words!
Quick question: Should interfaces have virtual destructors? Makes sense for enforcing resources cleanup. @MikeShah
Yes -- this is one of those C++ idioms where an interface (or base class in general) should have a virtual destructor. I have some videos on the playlist otherwise with further explanation here: ua-cam.com/video/XvzgC5WoBCE/v-deo.html
Hi Mike, Love the C++ series! I have a question that I'm having trouble finding the answer to. Is it bad practice to have an interface class but have the derived classes not fully implement the member functions? I have a settings classes that contains several member functions for every possible output (minValue,maxValue,settingName,value,listOfOptions(think drop down menu). But every setting needs these members. Ex: A toggle setting only needs value and settingName, not listOfOptions. I haven't gotten to your c++ design patterns, I'm not sure if its talked about there. Any help is greatly appreciated. Should a be avoid this design? The only way I know to add derived objects to a list would be to pass the based pointers to avoid object slicing.
Hard to say without seeing code, but sometimes a derived class may not implement all the behaviors of the base class. In practice that's why we fall back to the base classes behavior. If you have a true interface (lots of pure virtual functions) and many members are not implemented, that could be a sign that it's not the same type. You could consider the strategy pattern in your situation if you just need to configure behavior based on inputs
@@MikeShah wow thanks for such a quick response! I'll look into the stagety design pattern. Is this a question appropriate for your community forum? I could provide a more detailed explanation of what I'm trying to do along with code.
@@Matt-jd1zk Yup, that's a good place for it -- will take a look (or someone for the community might) when I can!
Hi Mike, thanks for the great explanation! I do have one question though. I swapped out your usage of a raw pointer for a unique_ptr and I added default constructors and destructors to IRenderer, OpenGL and Vulkan classes each with some std::cout statements for "constructing X", "destructing X". I notice that when creating a new instance of the child class the constructor of the base class is called, then the constructor of the child class but at the termination of scope only the base destructor is called and not the child destructor? Why is this? Does that mean I have a memory leak of the child class?
A little bit of a special thing that you have to do is make the destructor virtual for the base class to ensure both will get called -- give that a try :)
how did you get Indian surname? are you Indian?
😁Maybe a future episode I'll talk about my origin story