[英]boost::shared_ptr, access to a variable after inheritance?
我使用MonkSVG庫:
類對象定義為:
//mkSVG.h
namespace MonkSVG {
using namespace std;
class SVG;
class ISVGHandler {
public:
typedef boost::shared_ptr<ISVGHandler> SmartPtr;
...
ISVGHandler::SmartPtr _handler;
...
然后,該庫的作者定義了另一個類 :
class OpenVG_SVGHandler : public ISVGHandler
它是可以訪問到的變量ISVGHandler
通過_handler
從SVG
。
我繼承了我自己的2個類:第一個是從ISVGHandler
,第二個是從SVG
繼承的,第一個有其自己的變量,但是我無法直接訪問它們。 我發現的唯一解決方案是創建一個setter-getter方法,但是即使如此,我也需要在根類和最后一個繼承的類中定義它們。
有更好的解決方案嗎?
您應該使用ISVGHandler定義自己的處理程序,但是要添加和使用新功能,還需要制作派生的SVG。 SVG必須具有處理程序才能工作,因此您可以同時使它們同時工作,也可以通過初始化檢查來確定。
#define MAKE_YOUR_OWN_HANDLER
#include <iostream>
#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>
// darned compiler not up to date
#define nullptr NULL
class ISVGHandler {
protected:
ISVGHandler(){} // interface, must be derived
public:
virtual ~ISVGHandler(){}
typedef boost::shared_ptr<ISVGHandler> SmartPtr;
void onPathBegin() {std::cout << "base onPathBegin" << std::endl;}
void onPathEnd() {std::cout << "base onPathEnd" << std::endl;}
};
class OpenVG_SVGHandler : public ISVGHandler {
public:
typedef boost::shared_ptr<OpenVG_SVGHandler> SmartPtr;
static ISVGHandler::SmartPtr create() {
return boost::make_shared<OpenVG_SVGHandler>();
}
void draw() {std::cout << "openvg draw" << std::endl;}
void optimize() {std::cout << "openvg optimize" << std::endl;}
};
class WrongHandler : public ISVGHandler {
public:
typedef boost::shared_ptr<OpenVG_SVGHandler> SmartPtr;
static ISVGHandler::SmartPtr create() {
return boost::make_shared<WrongHandler>();
}
void draw() {std::cout << "openvg draw" << std::endl;}
void optimize() {std::cout << "openvg optimize" << std::endl;}
};
class SVG {
public:
virtual ~SVG(){}
bool initialize(ISVGHandler::SmartPtr handler) {
_handler = handler;
std::cout << "base init" << std::endl;
return true;}
void onPathBegin() {_handler->onPathBegin();}
void onPathEnd() {_handler->onPathEnd();}
private:
ISVGHandler::SmartPtr _handler;
};
class OpenVG_SVG : public SVG {
private:
OpenVG_SVGHandler * m_pOpenVG_Handler;
public:
#ifdef MAKE_YOUR_OWN_HANDLER
OpenVG_SVG(){
// use factory to make correct handler
ISVGHandler::SmartPtr spBaseHandler (OpenVG_SVGHandler::create());
// store known handler type for this class to use
m_pOpenVG_Handler = reinterpret_cast<OpenVG_SVGHandler*>(spBaseHandler.get());
// initialize the SVG base class
initialize(spBaseHandler);
}
#else
OpenVG_SVG() : m_pOpenVG_Handler(nullptr) {}
bool initialize(ISVGHandler::SmartPtr handler){
try {
m_pOpenVG_Handler = dynamic_cast<OpenVG_SVGHandler*>(handler.get());
if (m_pOpenVG_Handler){
std::cout << "openvg svg init" << std::endl;
return SVG::initialize(handler);
} else {
std::cout << "wrong handler" << std::endl;
}
} catch (std::exception &e){
std::cout << "wrong handler: " << e.what() << std::endl;
}
return false;
}
#endif
// write functions that are OpenVG specific in this class, using m_pOpenVG_Handler
void draw() { m_pOpenVG_Handler->draw(); } // I'd check for null but that's not relevant to the question
void optimize() {m_pOpenVG_Handler->optimize(); }
// let the virtual functions handle all the other behavior.
};
int test_svg()
{
OpenVG_SVG ovg;
#ifndef MAKE_YOUR_OWN_HANDLER
ovg.initialize(OpenVG_SVGHandler::create());
#endif
ovg.draw();
ovg.onPathBegin();
ovg.onPathEnd();
ovg.optimize();
#ifndef MAKE_YOUR_OWN_HANDLER
std::cout << "attempting to initialize with wrong handler:" << std::endl;
OpenVG_SVG bad;
if (bad.initialize(WrongHandler::create())){
bad.draw();
}
#endif
return 0;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.