本帖最后由 xulin_2005 于 2012-9-17 15:09 编辑
问题描述: 在制作自定义的拖拽器时,想继承其自带的Constraint类来实现对模型拖拽的约束,但发现在VS2005下的STL的vector下,因为类型的强制转换,导致了在调用拖拽器时,对象的类型被强制改成了父类型,导致无法使用继承后的Constraint类,想问下谁有什么好的办法可以改进? 相关代码和描述: Dragger.cpp中的代码: (*itr)->constrain(command); // 关键这里的强制转换把指针的真实类型给截断掉了 - void Dragger::dispatch(MotionCommand& command)
- {
- // apply any constraints
- for(Constraints::iterator itr = _constraints.begin();
- itr != _constraints.end();
- ++itr)
- {
- (*itr)->constrain(command); // 关键这里的强制转换把指针的真实类型给截断掉了
- }
- // move self
- getParentDragger()->receive(command);
- for(DraggerCallbacks::iterator itr = getParentDragger()->getDraggerCallbacks().begin();
- itr != getParentDragger()->getDraggerCallbacks().end();
- ++itr)
- {
- (*itr)->receive(command);
- }
- }
复制代码
Constraint中的代码 virtual bool constrain(MotionCommand&) const { return false; } // 永远只会调用这一句
- class OSGMANIPULATOR_EXPORT Constraint : public osg::Referenced
- {
- public:
- virtual bool constrain(MotionCommand&) const { return false; } // 永远只会调用这一句
- virtual bool constrain(TranslateInLineCommand& command) const { return constrain((MotionCommand&)command); }
- virtual bool constrain(TranslateInPlaneCommand& command) const { return constrain((MotionCommand&)command); }
- virtual bool constrain(Scale1DCommand& command) const { return constrain((MotionCommand&)command); }
- virtual bool constrain(Scale2DCommand& command) const { return constrain((MotionCommand&)command); }
- virtual bool constrain(ScaleUniformCommand& command) const { return constrain((MotionCommand&)command); }
- …
复制代码
Vector中的代码
return ((reference)**(_Mybase *)this); // 这里的_Mybase类型和reference类型转换把原先的类型给截断了
- reference operator*() const
- { // return designated object
- return ((reference)**(_Mybase *)this); // 这里的_Mybase类型和reference类型转换把原先的类型给截断了
- }
复制代码
验证vector中的示例代码: 在下面的例子中我用了一个 vector 存放 ref_ptr<CDoParent> 的指针列表,在 OutInfo() 中,用迭代器重新遍历获取出来,再调用,发现此时调用的全都是 CDoParent:o(CCmd & cmd),其他的已经无法调用了。 - class CCmd;
- class CDoParent : public osg::Referenced
- {
- public:
- void Do( CCmd & cmd ) { cout << "CDoParent::Do(CCmd & cmd);" << endl; }
- };
- class CADo : public CDoParent
- {
- public:
- void Do( CCmd & cmd ) { cout << "CADo::Do(CCmd & cmd);" << endl; }
- };
- class CBDo : public CDoParent
- {
- public:
- void Do( CCmd & cmd ) { cout << "CBDo::Do(CCmd & cmd);" << endl; }
- };
- class CCmd : public osg::Referenced
- {
- protected:
- virtual ~CCmd() {};
- std::vector<osg::ref_ptr<CDoParent>> m_doList;
- std::vector<osg::ref_ptr<CDoParent>>::iterator m_doListIter;
- public:
- CCmd() {};
- void addDo(CDoParent & todo) { m_doList.push_back(&todo); }
- virtual void f( CDoParent & todo ) { todo.Do(*this); }
- virtual void f( CADo & todo ) { todo.Do(*this); }
- virtual void f( CBDo & todo ) { f((CDoParent&)todo); }
- void OutInfo()
- {
- for ( m_doListIter = m_doList.begin(); m_doListIter != m_doList.end(); ++m_doListIter )
- {
- CDoParent doParent;
- CADo Ado;
- CBDo Bdo;
- //f(*(m_doListIter->get()));
- if ( typeid(CDoParent) == typeid(m_doListIter->get()) )
- f( doParent );
- else if ( typeid(CADo) == typeid(m_doListIter->get()) )
- f( Ado );
- else if ( typeid(CBDo) == typeid(m_doListIter->get()) )
- f( Bdo );
- else
- cout << "can't find the type" << endl;
- }
- }
- };
- class CMotionCmd : public CCmd
- {
- protected:
- virtual ~CMotionCmd() {};
- public:
- CMotionCmd() {};
- virtual void f( CDoParent & todo ) { cout << "CMotionCmd::f() {" << endl; todo.Do(*this); cout << "}" << endl; }
- virtual void f( CADo & todo ) { cout << "CMotionCmd::f() {" << endl; todo.Do(*this); cout << "}" << endl; }
- virtual void f( CBDo & todo ) { cout << "CMotionCmd::f() {" << endl; f((CDoParent &)todo); cout << "}" << endl; }
- };
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- void test()
- {
- std::vector< osg::ref_ptr<CCmd>> cmdList;
- std::vector< osg::ref_ptr<CCmd>>::iterator cmdListIter;
- osg::ref_ptr<CDoParent> todo = NULL;
- osg::ref_ptr<CCmd> cmd = NULL;
- cmd = new CCmd;
- todo = new CDoParent;
- cmd->addDo(*(todo.release()));
- todo = new CADo;
- cmd->addDo(*(todo.release()));
- todo = new CBDo;
- cmd->addDo(*(todo.release()));
- cmdList.push_back(cmd.release());
- cmd = new CMotionCmd;
- todo = new CDoParent;
- cmd->addDo(*(todo.release()));
- todo = new CADo;
- cmd->addDo(*(todo.release()));
- todo = new CBDo;
- cmd->addDo(*(todo.release()));
- cmdList.push_back( cmd.release());
- for ( cmdListIter = cmdList.begin(); cmdListIter != cmdList.end(); ++cmdListIter )
- {
- (*cmdListIter)->OutInfo();
- }
- }
复制代码
|