I have the following program that I attempt to use function pointer to "save memory",by saving an address of a function to a member variable, which is the function pointer.
The function pointer is provideService_proxy
which is defined by typedef void (* provideService_proxy )(std::string product)
.
I attempt to instantiate RealShop realShop_ and then call RealShop::provideService(string product)
. Furthermore, I want to save the address of provideService
.
However, I encounter an error. Could you please help?
#include "iostream"
#include "string"
using namespace std;
// needed preprocessor to prevend loop include
#ifndef ISHOP
#define ISHOP
#include "string"
class IShop{
public:
IShop(){};
virtual void provideService(std::string product) = 0;
virtual ~IShop(){};
};
#endif
class RealShop: public IShop {
public:
RealShop(){};
virtual ~RealShop(){};
virtual void provideService(std::string product) override{
cout<<" shop is building "<<product<<" in warehouse"<<endl;
if (specialOrder_ == true){
specialService("Minh");
}
collectMaterial();
} ;
private:
static const bool specialOrder_ = true;
void collectMaterial(){
cout<<" collect material to build product"<<endl;
};
void specialService(std::string customerName){
std::cout<<"provide custom order to customer "<<customerName<<std::endl;
customerName_ = customerName;
}; // newly added
std::string customerName_;
};
class ShopProxy : public IShop {
public:
ShopProxy(){};
virtual ~ShopProxy(){};
virtual void provideService(std::string product) override {
if ( realShop_ == nullptr ) {
std::cout<<"Proxy creates RealShop on request"<<std::endl;
// realShop_ = new RealShop(); //create RealShop, call RealShop to do service
// provideService_proxy = reinterpret_cast<provideService_proxy>(&RealShop::provideService);
provideService_proxy = init_RealService (product);
}
else{
std::cout<<"Proxy can provide service"<<std::endl;
// RealShop is available in Proxy's memory.
// don't have to reload, just run logic
// realShop_ ->provideService(product);
provideService_proxy (product);
}
};
private:
typedef void (* provideService_proxy )(std::string product);
provideService_proxy init_RealService ( std::string product ){
realShop_ = new RealShop();
return reinterpret_cast<provideService_proxy>(&RealShop::provideService);
};
RealShop * realShop_ = nullptr; // safe initialization of pointer
};
int main()
{
std::string requestProduct1 = "a doll";
IShop * myShopProxy = new ShopProxy();
// myShopProxy creates RealShop
myShopProxy->provideService(requestProduct1);
// myShopProxy already has RealShop, and can provide service.
std::string requestProduct2 = "a toy";
myShopProxy->provideService(requestProduct1);
// delete myShopProxy will delete RealShop and data saved in memory
delete myShopProxy;
// create new proxy
IShop * myShopProxy2 = new ShopProxy();
// myShopProxy has to create new RealShop again and reload data.
myShopProxy2->provideService(requestProduct1);
delete myShopProxy2;
}
The error is:
error: expected unqualified-id before '=' token
50 | provideService_proxy = init_RealService (product);
There are several errors in my program:
First, I got confused and forgot to declare a member function pointer:
void (* provideService_proxy )(std::string product) = nullptr;
Instead, I had only the data type of function pointer by this line:
typedef void (* provideService_proxy )(std::string product)
Secondly, in order to assign the address of RealShop::provideService(string)
to the function pointer, I need a more straighforward and explicitly defined the function pointer as:
void (RealShop::* provideService_proxy )(std::string) = nullptr ;
To save the address of RealShop::provideService(string)
, I have to do the following:
realShop_ = new RealShop();
provideService_proxy = &RealShop::provideService;
(realShop_->*provideService_proxy)(product);
In order to call RealShop::provideService(string)
via function pointer, I have to do:
(realShop_->*provideService_proxy)(product);
This is my final program:
#include "iostream"
#include "string"
using namespace std;
// needed preprocessor to prevend loop include
#ifndef ISHOP
#define ISHOP
#include "string"
class IShop{
public:
IShop(){};
virtual void provideService(std::string product) = 0;
virtual ~IShop(){};
};
#endif
class RealShop: public IShop {
public:
RealShop(){
cout<<"RealShop constructor"<<endl;
};
virtual ~RealShop(){
cout<<"RealShop destructor"<<endl;
};
virtual void provideService(std::string product) override{
cout<<" shop is building "<<product<<endl;
} ;
};
class ShopProxy : public IShop {
public:
ShopProxy(){
cout<<"**ShopProxy constructor**"<<endl;
};
virtual ~ShopProxy(){
cout<<"**ShopProxy destructor**"<<endl;
delete realShop_;
};
virtual void provideService(std::string product) override {
if ( realShop_ == nullptr ) {
//create RealShop, call RealShop to do service
// provideService_proxy = (void (*)(std::string))init_RealService (product);
init_RealService (product);
}
else{
std::cout<<"Proxy can provide service"<<std::endl;
// RealShop is available in Proxy's memory.
// don't have to request another function call, and add to stack
// save stack memory by using function pointer.
(realShop_->*provideService_proxy)(product);
}
};
private:
// typedef void (* functPtr )(std::string product);
// void (* provideService_proxy )(std::string product) = nullptr;
void (RealShop::* provideService_proxy )(std::string) = nullptr ;
void init_RealService ( std::string product ){
std::cout<<"Proxy creates RealShop on request"<<std::endl;
realShop_ = new RealShop();
std::cout<<"init_RealService saves realShop_->provideService to function pointer"<<endl;
provideService_proxy = &RealShop::provideService;
(realShop_->*provideService_proxy)(product);
};
RealShop * realShop_ = nullptr; // safe initialization of pointer
};
int main()
{
std::string requestProduct1 = "REQUEST 1: a doll";
IShop * myShopProxy = new ShopProxy();
// myShopProxy creates RealShop
myShopProxy->provideService(requestProduct1);
// myShopProxy already has RealShop, and can provide service.
std::string requestProduct2 = "REQUEST 2: a toy";
myShopProxy->provideService(requestProduct2);
// delete myShopProxy will delete RealShop and data saved in memory
delete myShopProxy;
// create new proxy
std::string requestProduct3 = "REQUEST 3: a fan";
IShop * myShopProxy2 = new ShopProxy();
// myShopProxy has to create new RealShop again and reload data.
myShopProxy2->provideService(requestProduct3);
delete myShopProxy2;
}
Thanks @Vlad From Moscow for the help!