Error expected unqualified-id before '=' token when assigning a function pointer to the address of another function

246 Views Asked by At

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);
2

There are 2 best solutions below

0
Minh Pham On BEST ANSWER

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!

5
Vlad from Moscow On

This typedef declaration

typedef void (* provideService_proxy )(std::string product);

declares the name provideService_proxy as an alias for the type void ( * )( std::string ). It does not declare any object of the pointer type.

So using this typedef name as an object in the expression statement

provideService_proxy = init_RealService (product);

produces an error.

Pay attention to that you need to declare a pointer to member function not to a stand alone function.