boost::shared_ptr,继承后访问变量

boost::shared_ptr, access to a variable after inheritance?

本文关键字:访问 变量 继承 ptr shared boost      更新时间:2023-10-16

我使用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 

并且可以从SVG经由_handler访问ISVGHandler的变量。

我继承了自己的两个类:第一个来自ISVGHandler,第二个来自SVG,第一个有自己的变量,但我无法直接访问它们。我找到的唯一解决方案是创建一个setter-getter方法,但即便如此,我也需要在根类和最后继承的类中定义它们。

有什么更好的解决方案吗?

您应该使用ISVGHandler定义自己的处理程序,但要添加和使用新函数,您还需要生成派生的SVG。您的SVG必须有处理程序才能工作,因此您可以同时进行这两种处理,也可以让initialize为您检查它以确保其正常工作。

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