Conversions between object types - c++

What I'm trying to do:
void startApp() {
//create validator
MedValidator* val = new MedValidator();
//create reporsitory
MedicineRepository* repo= new MedRepo() ;
//create controller
Control wh(repo, val);
...}
Here is a view at the used types:
class MedValidator
{
public:
void validate(const Medicine& s) throw(MedException);
};
class MedicineRepository
{
public: virtual void addMed(Medicine s) ;
};
class MedRepo : public MedicineRepository{
public:void addMed(Medicine s);
protected:
Vector<Medicine*> MedList;
};
I get Multiple markers at this line
- candidates are:
- no matching function for call to 'Control::Control(MedicineRepository&,
MedValidator*&)' at startApp() when I'm declaring wh
class Control {
public:
Control(MedRepo* repo, MedValidator* validator);};
How can I fix this?I hope the amount of code is enough,if it's needed more I'll add.

The constructor for Control takes a MedRepo* argument:
Control(MedRepo* repo, MedValidator* validator);};
But you are passing a MedicineRepository*:
MedicineRepository* repo= new MedRepo() ;
//create controller
Control wh(repo, val);
Also, don't use exception specifications, they're bad.

Your problem is that MedRepo is a MedicineRepository but MedicineRepository is not a MedRepo. You can't substitute a base class object where a derived class object is expected, only the reverse (safely, anyway). You need to figure out if you need a pointer to that specific derived class or if a pointer to any derived class is okay. For the former keep your code how it is and send it a MedRepo object. If any derived class will do (i.e. you're only accessing methods from the base class) then change Control to accept the base class instead.

Related

Initializing a new nested class from outer class function

I'm currently learning nested classes in C++ while building a project and I currently inside setupBLE() I need to pass one of the nested classes but to init that new class I need to pass to its constructor the outer class so it can access its variables and functions but I'm not exactly sure how to pass to the constructor the pointer of the class that's trying to create it.
It's a bit confusing so I hope the code helps with it.
Like in python we have self but in C++ as far as I know we don't have that so I was wondering what should I pass to the constructor.
Code (PillDispenser.h):
class PillDispenser {
public:
explicit PillDispenser(BLEAddress deviceAddress);
private:
BLEAddress _device_address;
BLEAdvertisedDevice _device;
bool _connected;
// Device properties
std::string _device_name;
// Callbacks
static void notifyCallBack();
class AdvertisedDeviceCallBack : public BLEAdvertisedDeviceCallbacks {
PillDispenser &_outer;
explicit AdvertisedDeviceCallBack(PillDispenser &outer) : _outer(outer){};
void onResult(BLEAdvertisedDevice advertisedDevice) override;
};
}
Code (PillDispenser.cpp):
void PillDispenser::setupBLE() {
BLEScan *scanner = BLEDevice::getScan();
scanner->setAdvertisedDeviceCallbacks(new AdvertisedDeviceCallBack());
scanner->setInterval(SCAN_INTERVAL);
scanner->setWindow(SCAN_WINDOW);
scanner->setActiveScan(true);
scanner->start(SCAN_DURATION);
}
Issue:
This line is trying to use the default constructor which does not exist
scanner->setAdvertisedDeviceCallbacks(new AdvertisedDeviceCallBack());
instead you should use the explicit constructor you defined
scanner->setAdvertisedDeviceCallbacks(new AdvertisedDeviceCallBack(*this));
note that this (in this context) has type PillDispenser* so you have to dereference with * to get a PillDispenser&

Passing vector by reference to another class/file

I have 2 sets of header+source files. One with the Main GUI class and the other with a Derived GUI class (Main window that opens a second window).
In the Main class I have a vector of strings. I can pass that vector by reference by calling a function in the Derived class and pass it by reference. I can use and update that vector in this function and the changes will be available in the Main class/file. So far so good.
The next thing I would like to do is use this passed by reference vector in all functions in the Derived class.
Up to now, I created and 'extern' vector in a "common" set of header+source.
This make it a global vector, and although its working, it is not the most elegant way.
Is there an alternative way to make the vector available to all functions in the Derived GUI class/file (and add/edit elements that are available in the Main GUI class/file later on)?
MainFrame.h
class wxMainFrame: public GUIFrame
{
public:
wxMainFrame(wxFrame *frame);
~wxMainFrame();
DerivedFrame *m_DerivedFrame;
private:
std::vector<wxString> vwsM3;
....etc
}
DerivedFrame.h
class DerivedFrame: public OtherFrane
{
public:
DerivedFrame( wxWindow* parent );
~DerivedFrame();
private:
std::vector<wxString> vwsM4;
void PassVector(std::vector<wxString> &vwsM);
void USEvwsM();
....etc
}
MainFrame.cpp
wxMainFrame::wxMainFrame(wxFrame *frame) : GUIFrame(frame)
{
m_DerivedFrame = new DerivedFrame(this);
m_DerivedFrame->PassVector(&vwsM3);
}
DerivedFrame.cpp
DerivedFrame::DerivedFrame ( wxWindow* parent ) : OtherFrame( parent )
{
//
}
void DerivedFrame::PassVector(std::vector<wxString> &vwsM)
{
vwsM.push_back("Something");
}
void USEvwsM()
{
// ??
}
OnInit() (The vector vwsM3 is not known here because its in a seperate header+source file)
IMPLEMENT_APP(wxMainApp);
bool wxMainApp::OnInit()
{
wxMainFrame* frame = new wxMainFrame(0L);
frame->SetIcon(wxICON(aaaa)); // To Set App Icon
frame->Show();
return true;
}
To derived class add one more pointer field:
class DerivedFrame: public OtherFrame {
.......
private:
std::vector<wxString> * pvwsM3 = nullptr;
.......
};
Modify PassVector() method to fill pointer:
void DerivedFrame::PassVector(std::vector<wxString> & vwsM) {
pvwsM3 = &vwsM;
}
Use pointer now:
void DerivedFrame::USEvwsM() {
assert(pvwsM3); // Check that we don't have null pointer, you may throw exception instead.
pvwsM3->push_back("Something");
}
Remaining code is same as you have. Alternatively you may pass vector to constructor of DerivedFrame, which is more reliable than calling PassVector() separately (which you may forget to call, while constructor you always call):
DerivedFrame::DerivedFrame(wxWindow* parent, std::vector<wxString> & vwsM)
: OtherFrame( parent ) {
this->PassVector(vwsM);
}
If you pass vector of strings to constructor only then you don't need a pointer, but reference in derived class, so instead of pointer field
class DerivedFrame: public OtherFrame {
std::vector<wxString> * pvwsM3 = nullptr;
.......
};
make reference field
class DerivedFrame: public OtherFrame {
std::vector<wxString> & rvwsM3;
.......
};
then remove PassVector() method and add reference initialization in constructor:
DerivedFrame::DerivedFrame(wxWindow* parent, std::vector<wxString> & vwsM)
: OtherFrame( parent ), rvwsM3(vwsM) {}
and use it as a reference (unlike pointer reference doesn't need to be checked for null):
void DerivedFrame::USEvwsM() {
rvwsM3.push_back("Something");
}
Reference compared to pointer has two advantages - it can't be forgotten to be initialized, because with reference you don't need to call PassVector(), and you don't need to check if it is null unlike checking pointer (reference is never null). But reference can be initialized only in constructor, while pointer can be initialized later, far later after object was constructed.
Having a global vector is bad practice, but anyhow typical for a settings like vector.
When I understand right, the vector you want to share, is known in the base like this
struct base {
std::vector<std::string>& data;
base(std::vector<std::string>& init) : data(init) {}
};
struct derived : base {
derived(std::vector<std::string>& init) : base(init) {}
void have_fun_with_VectorOfStrings();
};
it can be directly accessed in derived class, or any entity having access to one of the derived class.
Not sure if you might be looking for a different approach like the singleton pattern instead:
class coolStuff {
public:
std::vector<std::string> data;
static coolStuff& get() {
static coolStuff instance;
return instance;
}
private:
coolStuff () {
// constructor called once using "get", so can be used for initialization
}
};
This would be simply called anywhere you need it. Since only 1 instance exists, it might be a better approach to achieve the same.
coolStuff::get().data.push_back("add a new string");
You have shared a code example meanwhile, so your example would look like this applying approach 1 above.
class wxMainFrame: public GUIFrame {
public:
wxMainFrame(wxFrame *frame, std::vector<wxString>& vwsM3);
private:
std::vector<wxString>& vwsM3;
};
wxServerFrame::wxServerFrame(wxFrame *frame, std::vector<wxString>& _vwsM3) : GUIFrame(frame)
, vwsM3(_vwsM3)
{
m_DerivedFrame = new DerivedFrame(this, _vwsM3);
// m_DerivedFrame->PassVector(&vwsM3); // not needed anymore
}
// same for further inherited classes
If I may add a side note: It looks like you are doing some graphic-like stuff, so performance should be considered aswell: Try to avoid dynamic allocations like new, mallcoc, etc, since this is a very slow operation. An optimization might be to use a member in the class, instead of allocating to a member pointer at runtime.

Making a kind of switch case for inherited classes by type

I've got a base class calls:
class item
{
public:
item();
virtual string act()=0;
};
and a few classes that inherit from this one;
class food:item
{
public:
food();
string act();
};
class ant:item
{
public:
ant(unsigned int new_ant);
~ant();
string act();
};
class anthill:item
{
public:
anthill();
string act();
}
then I've got a list that serves as a container of several instances of those classes.
I iterate through the list.
Now I've to use different functions depending on the type of the instance that are hidden behind the Iterator.
but I can't find a way to distinguish between e.g. an ant and food
I've tried comparisons with typeinfo
as well as
ant* test = dynamic_cast<ant *>((*i)); // returns nullptr even though debug says i is an ant
ant* test = dynamic_cast<ant *>((*i)); // returns nullptr even though debug says i is an ant
That's because your classes use private inheritance. Change them to use public inheritance.
Use
// |
// v
class food : public item
{
public:
food();
string act();
};
I have done this by using containers of type_info hash codes to function pointers, For example a language interpreter implemented operator resolution by having maps like the following:
std::unordered_map<std::pair<size_t, size_t>, add_func*>fnsAdd = boost::assign::map_list_of
(std::make_pair(typeid(integer_value).hash_code(), typeid(integer_value).hash_code()), (add_func*)&integer_value_integer_value_Add)
(std::make_pair(typeid(integer_value).hash_code(), typeid(real_value).hash_code()), (add_func*)&integer_value_real_value_Add)

Error while trying to use boost::factory

I am trying to use boost factory and I am experiencing the following problem.
All I am trying to do is having a bunch of derived classes to have a mechanism that will be initializing the derived class that is matched with a corresponding string.
To begin with I have the following base class called name NetWorkBlock,
NetWorkBlock.h
class NetWorkBlock {
protected:
typedef boost::function<NetWorkBlock * ()> NetWorkFactory;
//definition of the function that will be used for the factory
public:
NetWorkBlock();
virtual ~NetWorkBlock();
//some basic functionalities that not related to the factory
and thus not mentioned
static std::map<std::string,NetWorkBlock::NetWorkFactory>& f_factory();
//static function that initializes and returns the map
};
NetWorkBlock.cpp
NetWorkBlock::NetWorkBlock() {
} //empty constructor
NetWorkBlock::~NetWorkBlock() {
} //empty deconstructor
std::map<std::string,NetWorkBlock::NetWorkFactory>& NetWorkBlock::f_factory()
{
static std::map<std::string,NetWorkBlock::NetWorkFactory>* ans =
new std::map<std::string,NetWorkBlock::NetWorkFactory>();
return *ans;
} //initialization of map
Moving on here is how I define things in the the derived class BusNetworkBlock (note ofcourse
there are more derived classes expected to be defined later, but in the current moment I work with a single derived class to manage to have things working):
BusNetworkBlock.h
class BusNetworkBlock {
public:
BusNetworkBlock();
virtual ~BusNetworkBlock();
//some basic functionalities that not related to the factory
and thus not mentioned
private:
/* Very small, "fake" class _initializer. Its only meaning is to define a
static member _init that is initialized at the very beginning of the
main(). Hence the constructor is called, and the constructor registers
the BusNetworkBlock class into the (static) NetWorkBlock::f_factory. */
static class _init {
public:
_init() {
NetWorkBlock::f_factory()["LoadCurve"] = boost::factory<BusNetworkBlock *>();
}
}_initializer;
};
BusNetworkBlock.cpp
BusNetworkBlock::BusNetworkBlock() {
} //empty constructor
BusNetworkBlock::~BusNetworkBlock() {
} //empty deconstructor
/* The definition of the bodies of the funcionalities of the class that are not mentioned here since they are not connected with the factory */
BusNetworkBlock::_init BusNetworkBlock::_initializer;
/* Ensure that the static member _initializer is initialized, so that
BusNetworkBlock is registered into NetWorkBlock::f_factory. */
Now in an other separate class under the name UCBlock I try to use the factory in order to initialize properly the derived NetworkBlock class based on a string I receive in the following way:
UCBlock.h
class UCBlock {
public:
UCBlock(std::istream& inStream); //the received instream
virtual ~UCBlock();
//some basic functionalities that not related to the factory
and thus not mentioned
NetWorkBlock * Network; /*defining a pointer of the base class NetWorkBlock
that want to initialize properly via the factory */
};
UCBlock.cpp
UCBlock::UCBlock( std::istream& inStream ) {
inStream >> network; //setting the string of network the corresponding factory
Network = NetWorkBlock::f_factory()[network](); // set the corresponding object via factory **here is where the problem arises**
}
And the problem arises when I try to use the factory to proper initialize the
derived class of NetWorkBlock. I receive the following error:
terminate called after throwing an instance of 'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::bad_function_call> >'
what(): call to empty boost::function
Aborted (core dumped)
Now I have ofcoruse tried to check this thing online but didn't manage to come up with a solution and that's why I would really appreciate any kind of help here, since I am really stacked here. (Note also that I checked that the string I receive is correct and matches with "LoadCurve").

Converting objects of base class to derived class

I asked a couple days ago some clarifications on inheritance, a concept I am still trying to understand. Here is the follow up question, since I am still facing problems.
In my project I have 2 types of objects, Hand and Face, both inheriting from the base class BodyPart. BodyPart is something like this:
class BodyPart
{
public:
typedef boost::shared_ptr<BodyPart> BodyPartPtr;
BodyPart();
virtual ~BodyPart();
private:
int commonMember1;
double commonMember2;
public:
int commonMethod1();
int CommonMethod2();
}
while Hand is something like this:
class Hand : public BodyPart
{
public:
Hand();
~Hand();
private:
int numFingers;
double otherVar;
public:
int getNumFingers();
void printInfo();
}
I also have a vector of BodyPart elements
std::vector<BodyPart::BodyPartPtr> cBodyParts;
composed of Hand or Head objects. In the previous question I was told that this approach makes sense, I just had to cast from the base class to the derived using boost static_pointer_cast
Now, the problem now is that for some of the objects in the vector I don't know whether they are Hand or Head, so at some point in my code I can have in cBodyParts some Hand elements, some Head elements as well as some BodyPart elements. After some further analysis I am able to correctly classify the latter as either Hand or Head and modify accordingly the elements in the vector, but I have no idea on how to make it. Shall I just delete the case class element and create a derived one with the same property? Shall I just avoid inheritance in case like this?
Thanks in advance for the help
EDIT: I have augmented the examples to make them clearer.
Relaying on casts is usually a sign of a bad design. Casts have their place, but this does not look to be it.
You need to ask yourself what do you want to do with the objects stored in cBodyParts. For sure, you will be doing different things with a Hand or with a Head, but you can probably abstract them somehow: this is what virtual functions do. So, in addition to what you have already written for your classes, you would just need an additional virtual function in them:
class BodyPart
{
// Same as you wrote, plus:
public:
virtual void InitialisePart() = 0; // Pure virtual: each body part must say how to process itself
virtual void CalibrateJoints() {} // Override it only if the body part includes joints
}
class Head : public BodyPart
{
// Same as you wrote, plus:
public:
virtual void InitialisePart() {
// Code to initialise a Head
}
// Since a Head has no joints, we don't override the CalibrateJoints() method
}
class Hand : public BodyPart
{
// Same as you wrote, plus:
public:
virtual void InitialisePart() {
// Code to initialise a Hand
}
virtual void CalibrateJoints() {
// Code to calibrate the knuckles in the hand
}
}
And then you no longer need any casts. For instance:
for (BodyPart::BodyPartPtr part : cBodyParts) {
part->InitialisePart();
part->CalibrateJoints(); // This will do nothing for Heads
}
As you can see, no casts at all and everything will work fine. This scheme is extensible; if you later decide that you need additional classes inheriting from BodyPart, just write them and your old code will work correctly:
class Torso : public BodyPart
{
public:
virtual void InitialisePart() {
// Code to initialise a Torso
}
// The Torso has no joints, so no override here for CalibrateJoints()
// Add everything else the class needs
}
class Leg : public BodyPart
{
public:
virtual void InitialisePart() {
// Code to initialise a Leg
}
virtual void CalibrateJoints() {
// Code to calibrate the knee
}
// Add everything else the class needs
}
Now you don't need to change the code you wrote previously: the for loop above will work correctly with and Torso or Leg it finds with no need for an update.
The hip bone's connected to the thigh bone...
I take it you have some composite of all the body parts, maybe a Body class.
What do you want the body to do?
Render itself
Serialise
Ouput its volume, or bounding box, or some other metric
Re-orient itself in response to input
Respond to an inverse-kinematic physical model
The list could probably go on. If you know exactly what you want the Body to do you can put that function in the BodyPart base class, and have Body iterate over the composite hierarchical structure of all the connected body parts, calling render, for example.
An alternative is to use a Visitor, which is effectively a way of dynamically adding methods to a static inheritance hierarchy.
As Kerrek SB pointed out this is not feasible at all, but for the sake of answering the actual question, dynamic_cast is what you are looking for.
Use virtual functions, they will simplify a lot your problem.
Else, you can add some methods to distinguish between different types. However, do it only if you cannot do it another way, ie if you cannot do it via virtual functions.
Example 1:
// in BodyPart; to be reimplemented in derived classes
virtual bool isHand() const { return false; }
virtual bool isHead() const { return false; }
// in Hand (similar to what will be in Head)
bool isHand() const { return true; }
// How to use:
BodyPart::pointer ptr = humanBodyVector[42]; // one item from the array
if(ptr->isHand())
processHand(/*cast to hand*/)
else if(ptr->isHead())
// ...
Example 2: let the derived classes handle the cast
// in BodyPart; to be reimplemented in derived classes
virtual Hand* toHand() const { return 0; }
virtual Head* toHead() const { return 0; }
// in Hand (similar to what will be in Head)
Hand* toHand() const { return this; }