将函数指针分配给另一个函数的地址时,在'='标记之前出现错误预期的非限定ID

问题描述 投票:0回答:2

我有以下程序,我尝试使用函数指针来“节省内存”,方法是将函数的地址保存到成员变量,即函数指针。

函数指针为

provideService_proxy
,由
typedef void (* provideService_proxy )(std::string product)
定义。

我尝试实例化 RealShop realShop_,然后调用

RealShop::provideService(string product)
。此外,我想保存
provideService
.

的地址

但是,我遇到了一个错误。你能帮忙吗?

#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;
}

错误是:

error: expected unqualified-id before '=' token
   50 |             provideService_proxy = init_RealService (product);
c++ function-pointers implicit-conversion proxy-pattern
2个回答
2
投票

这个 typedef 声明

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

声明名称

provideService_proxy
作为类型
void ( * )( std::string )
的别名。它没有声明任何指针类型的对象。

所以在表达式语句中使用这个 typedef 名称作为对象

provideService_proxy = init_RealService (product);

产生错误。

注意你需要声明一个指向成员函数的指针而不是一个独立的函数。


0
投票

我的程序有几个错误:

首先,我搞糊涂了,忘了声明一个成员函数指针:

void (* provideService_proxy )(std::string product) = nullptr;

相反,我只有函数指针的数据类型:

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

其次,为了将

RealShop::provideService(string)
的地址分配给函数指针,我需要更直接明确地定义函数指针为:

void (RealShop::* provideService_proxy )(std::string) = nullptr ;

要保存

RealShop::provideService(string)
的地址,我必须执行以下操作:

realShop_ = new RealShop();
provideService_proxy = &RealShop::provideService;          
(realShop_->*provideService_proxy)(product);

为了通过函数指针调用

RealShop::provideService(string)
,我必须这样做:

(realShop_->*provideService_proxy)(product);

这是我的最终计划:

#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;
}

感谢来自莫斯科的@Vlad 的帮助!

© www.soinside.com 2019 - 2024. All rights reserved.