Initializing a new nested class from outer class function - c++

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&

Related

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.

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").

Using class references to modify public members within another class

Since my last question had too much code in it, I tried to make the simplest example of what I'm trying to do. Take this for example,..
#include <iostream>
using namespace std;
class String
{
public:
private:
};
class ClassTwo
{
public:
int memberVariable;
private:
};
class ClassOne
{
public:
ClassOne (ClassTwo&, String&);
~ClassOne();
private:
ClassTwo& classTwoReference;
String& stringReference;
};
ClassOne::ClassOne (ClassTwo& two, String& string)
: classTwoReference (two), stringReference (string)
{
two.memberVariable = 3;
}
ClassOne::~ClassOne()
{
}
int main()
{
String stringObject;
ClassTwo classTwoObject;
ClassOne classOneObject (classTwoObject, stringObject);
}
In JUCE, which is the API I'm using to code a VST Plugin, there is a string class that JUCE names "String". I'm not sure exactly what the constructor does, but you can use something like this to create a String object.
String newString("string");
The ClassTwo in my case, is the AudioProcessor class which has a public member variable that I can access from ClassOne like this.
two.memberVariable = 3;
The ClassOne in my case, is a custom Component(I named it PixelSlider) that I'm using in my GUI. It uses a slider listener to check the status of a slider and modify the member variable in ClassTwo(AudioProcessor). I can do this fine using the method above, but the issue is that I want to create as many ClassOne(PixelSlider) objects as I need. I want to pass them a String object that tells them what member variable of ClassTwo(AudioProcessor) to modify. Logically, this would be done by passing a reference to a String object with the same string value as the name of the ClassTwo member variable. Like this,...
ClassOne::ClassOne (ClassTwo& two, String& string)
: classTwoReference (two), stringReference (string)
{
two.(string) = 3;
}
This doesn't work in JUCE, but can anybody tell me a way to get this done without having to create a bunch of different classes almost exactly like ClassOne(PixelSlider) that modify different ClassTwo(AudioProcessor) member variables?
If I understand correctly, you're trying to bind a PixelSlider target to a member of AudioProcessor at runtime, which, as you've discovered, can't be done the way you suggest ( two.(string) = 3 ). One way of achieving this binding would be to use the command pattern (http://sourcemaking.com/design_patterns/command/cpp/2).
AudioProcessor could expose a collection of these command objects for each modifiable property ...
AudioProcessorCommand
AudioProcessor::GetCommandByName(String const& properyName) const
{
...
}
... which you can pass to the constructor of PixelSlider. Something along the lines of ...
PixelSlider::PixelSlider(AudioProcessorCommand& command)
: command_{command}
{
...
}
When the PixelSlider's value changes you would invoke the command ...
command_(this->value_);

Conversions between object types

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.

Combining function, bind, c++ and managed code

I have a c++ function which is expecting a function object (AuthenticateNotifyFunc) to be passed to it thus:
class lc_Authenticate
{
public:
typedef enum {
kAbort,
kContinue
} lc_AuthenticateStatus;
typedef std::tr1::function<lc_AuthenticateStatus (const string &msg)> AuthenticateNotifyFunc;
bool Authenticate(lc_AuthenticateParams &params,
AuthenticateNotifyFunc notifyFunc);
}
Within a managed c++ project, I am attempting to define a parameter to pass to the above function thus:
public ref class Form1 : public System::Windows::Forms::Form
{
public:
lc_Authenticate::lc_AuthenticateStatus UpdateStatus(const string &msg)
{
<<DO SOMETHING>>
return(lc_Authenticate::kContinue);
}
void test()
{
string appKey, appSecret;
appKey = GetString(this->appKeyTextBox->Text);
appSecret = GetString(this->appSecretTextBox->Text);
lc_Authenticate dbauth;
lc_AuthenticateParams params(appKey, appSecret);
// DOESN'T COMPILE won't let me take address of member function
// or know about _1
lc_Authenticate::AuthenticateNotifyFunc func =
std::tr1::bind(&Form1::UpdateStatus, this, _1);
dbauth.Authenticate(params, func);
}
};
So I am trying to implement a generic method of passing a function to a c++ method in such a way that it doesn't care whether the passed function is static or a member function. And I'm not clear how do do this from managed code.
You cannot bind to an instance method of a managed class by design. The garbage collector moves the object around when compacting the heap, causing this to change. You'll need to use a managed delegate. So you can't avoid a native helper class that provides the stable callback you need for your function<>. You can get back to managed code from there with Marshal::GetFunctionPointerForDelegate().