Oat++异步控制器非静态成员访问问题:如何访问成员对象?
Oat++异步控制器常见问题与解决方案
1. 异步API是否为静态?
OATPP通过ENDPOINT_ASYNC定义的异步端点是嵌套非静态类,并非静态API。框架处理请求时,会为每个请求创建端点类的实例,并将其关联到一个具体的控制器对象上,所有操作都基于该控制器实例执行,不存在静态调用的情况。
2. 访问控制器成员对象的解决方案
你遇到的编译错误,本质是异步端点的嵌套类无法直接引用外部控制器的私有成员,编译器误以为你要访问静态成员。以下是可行的解决方法:
核心思路
异步端点类内部自动包含一个controller指针,指向当前所属的MyController实例,通过这个指针可以访问控制器的成员。同时需要解决私有成员的访问权限问题,有两种方式:
方式一:声明异步端点类为控制器友元
在MyController的public区域添加友元声明,让异步端点类可以直接访问私有成员:
#include OATPP_CODEGEN_BEGIN(ApiController) class MyController : public oatpp::web::server::api::ApiController { public: friend class root; // 声明异步端点类为友元 ENDPOINT_INFO(root) { info->summary = "Example 'Root' endpoint. Without any params"; info->addResponse<Object<MessageDto>>(Status::CODE_200, "application/json"); } ENDPOINT_ASYNC("GET", "/hello", root){ ENDPOINT_ASYNC_INIT(root) Action act() override { auto dto = MessageDto::createShared(); dto->statusCode = 200; // 通过controller指针访问私有成员 if(controller->data_proccessor_ != nullptr) { // 调用data_proccessor_的方法 // controller->data_proccessor_->process(...); } dto->message = "Hello World!"; return _return(controller->createDtoResponse(Status::CODE_200, dto)); } }; private: const std::shared_ptr<i_data_proccessor> data_proccessor_ = nullptr; }; #include OATPP_CODEGEN_END(ApiController)
方式二:提供公共Getter方法
如果不想用友元,可为私有成员添加公共的获取方法,通过调用方法访问成员:
#include OATPP_CODEGEN_BEGIN(ApiController) class MyController : public oatpp::web::server::api::ApiController { public: // 公共Getter方法 std::shared_ptr<i_data_proccessor> getDataProcessor() const { return data_proccessor_; } ENDPOINT_INFO(root) { info->summary = "Example 'Root' endpoint. Without any params"; info->addResponse<Object<MessageDto>>(Status::CODE_200, "application/json"); } ENDPOINT_ASYNC("GET", "/hello", root){ ENDPOINT_ASYNC_INIT(root) Action act() override { auto dto = MessageDto::createShared(); dto->statusCode = 200; auto processor = controller->getDataProcessor(); if(processor != nullptr) { // 调用processor的方法 // processor->process(...); } dto->message = "Hello World!"; return _return(controller->createDtoResponse(Status::CODE_200, dto)); } }; private: const std::shared_ptr<i_data_proccessor> data_proccessor_ = nullptr; }; #include OATPP_CODEGEN_END(ApiController)
两种方式都能避免将data_processor设为单例,保持依赖注入的设计模式。
内容的提问来源于stack exchange,提问作者Botir Akhmedov
相关产品推荐
相关产品推荐

