OOP在C ++中这样做的方法? [英] OOPs way to do this in C++?
问题描述
我想在运行时更改类的方法。我正在制作一款游戏,并希望NPC对象根据游戏设计师采用不同的方法。那个
是,他们可能会决定这个暴徒应该能够飞行,是为了战斗,等等......而不是一堆开关声明或者
if..else我觉得能够在课堂上插入
函数/方法会很好。
嗯,这是旧的C方式,我在这里做过,但我对它不满意
。原因如下:
1.我必须为每个函数交朋友
2.我必须分配一个函数指针,那里可能会出错,加上
维持这是一种痛苦
3.这不是,IMO,它是最好的方式,但我不知道/>
更好的方式。
我只是在这里展示了这个动作的功能,但实际上会有一个运动之一的
一个用于战斗,一个用于防护(如果它是一个警卫),
等......
有关如何改进设计的任何建议?
#include< iostream>
#include< string>
class Base
{
朋友void Walk(Base& base);
朋友void Fly(Base& base);
朋友无效游泳(基地和基地);
朋友无效浮动(基地和基地);
公共:
基地(int X,const std :: string Movement):X(X),Move_(NULL)
{
if(Movement ==" Flies" )
Move_ = Fly;
else if(Movement ==Walks)
Move_ = Walk;
else if(Movement ==" Swims")
Move_ = Swim;
else if(Movement ==" Floats")
Move_ = Float;
else
Move_ =步行;
}
void Move (){if(Move_!= NULL){Move_(* this); } $
私人:
无效(*移动_)(基础&);
int X;
};
void Walk(Base& base)
{
base.X + = 5;
std :: cout<< 走到 << base.X<< " \ n";
}
void Fly(Base& base)
{
base.X + = 7;
std :: cout<< 飞到 << base.X<< " \ n";
}
无效游泳(基地和基地)
{
base.X + = 3;
std :: cout<< 游到 << base.X<< " \ n";
}
void Float(Base& base)
{
base.X + = 2;
std :: cout<< 浮动到 << base.X<< " \ n";
}
int main()
{
Base MyBase(10,Flies);
MyBase.Move();
std :: string wait;
std :: getline(std :: cin,wait);
}
问候,
Jim Langston
4月10日下午2:55,Jim Langston < tazmas ... @ rocketmail.comwrote:
我想在运行时更改类的方法。
尝试考虑:
http://en.wikipedia.org/wiki/Double_dispatch
http://en.wikipedia.org/wiki/Visitor_pattern
谢谢,
4月10日下午3:40,aiooua < aio ... @ gmail.comwrote:
4月10日下午2:55,Jim Langston < tazmas ... @ rocketmail.comwrote:
我想在运行时更改类的方法。
尝试考虑:
http://en.wikipedia.org/wiki/Double_dispatch
http://en.wikipedia.org/wiki/Visitor_pattern
Jim Langston写道:
有关如何改进的建议设计?
正如aiouua所说,正确答案是使用装饰模式。
无论如何,我想指出即使你的设计你不需要
任何朋友的功能。考虑一下:
#include< iostream>
#include< string>
#include< functional>
等级基础
{
私人:
无效行走();
void Fly();
void Swim();
void Float();
public:
Base(int X,const std :: string Movement):Move_(NULL),X(X)
{
if (运动==飞行)
Move_ = std :: mem_fun_ref(& Base :: Fly);
else if(Movement ==" Walks" )
Move_ = std :: mem_fun_ref(& Base :: Walk);
else if(Movement ==" Swims")
Move_ = std :: mem_fun_ref(& Base :: Swim);
else if(Movement ==" Floats")
Move_ = std :: mem_fun_ref( & Base :: Float);
else
Move_ = std :: mem_fun_ref(& Base :: Walk);
}
void Move(){Move _(* this); }
私人:
std :: mem_fun_ref_t< void,BaseMove_;
int X;
};
void Base :: Walk()
{
X + = 5;
std :: cout<< 走到 << X << " \ n";
}
void Base :: Fly()
{
X + = 7;
std :: cout<< 飞到 << X << " \ n";
}
void Base :: Swim()
{
X + = 3;
std :: cout<< 游到 << X << " \ n";
}
void Base :: Float()
{
X + = 2;
std :: cout<< 浮动到 << X << " \ n";
}
int main()
{
Base MyBase(10,Flies);
MyBase.Move();
std :: string wait;
std :: getline(std :: cin,wait);
返回0;
}
如前所述,它;更好的装饰,有一个基础与
虚拟Move()= 0;
和每个派生类实现不同的Move( )。
问候,
Zeppe
I want to change a class''s methods at run time. I''m making a game and want
NPC objects to have different methods depending on a game designer. That
is, they may decide that this mob should be able to fly for movement, be
agressivie for combat, etc... Rather than a bunch of switch statements or
if..else I was thinking it would be good to be able to plug in
functions/methods to the class.
Well, there''s the old C way, which I''ve done here, but am not happy with it
at all. For a few reasons:
1. I have to friend every function
2. I have to assign a function pointer, and things can go wrong there, plus
it gets to be a pain to maintain
3. It''s just not, IMO, the best way it could be, but I don''t know of a
better way.
I''ve only shown the function here for movement, but in reality there would
be one for movement, one for combat, one for guarding (if it''s a guard),
etc...
Any suggestions on how to improve the design?
#include <iostream>
#include <string>
class Base
{
friend void Walk( Base& base );
friend void Fly( Base& base );
friend void Swim( Base& base );
friend void Float( Base& base );
public:
Base( int X, const std::string Movement ): X(X), Move_( NULL )
{
if ( Movement == "Flies" )
Move_ = Fly;
else if ( Movement == "Walks" )
Move_ = Walk;
else if ( Movement == "Swims" )
Move_ = Swim;
else if ( Movement == "Floats" )
Move_ = Float;
else
Move_ = Walk;
}
void Move() { if ( Move_ != NULL ) { Move_( *this ); } }
private:
void (*Move_)( Base& );
int X;
};
void Walk( Base& base )
{
base.X += 5;
std::cout << "Walked to " << base.X << "\n";
}
void Fly( Base& base )
{
base.X += 7;
std::cout << "Flew to " << base.X << "\n";
}
void Swim( Base& base )
{
base.X += 3;
std::cout << "Swam to " << base.X << "\n";
}
void Float( Base& base )
{
base.X += 2;
std::cout << "Floated to " << base.X << "\n";
}
int main()
{
Base MyBase( 10, "Flies" );
MyBase.Move();
std::string wait;
std::getline( std::cin, wait );
}
Regards,
Jim Langston
On Apr 10, 2:55 pm, "Jim Langston" <tazmas...@rocketmail.comwrote:I want to change a class''s methods at run time.try considering:
http://en.wikipedia.org/wiki/Double_dispatch
http://en.wikipedia.org/wiki/Visitor_pattern
thanks,
On Apr 10, 3:40 pm, "aiooua" <aio...@gmail.comwrote:On Apr 10, 2:55 pm, "Jim Langston" <tazmas...@rocketmail.comwrote:I want to change a class''s methods at run time.try considering:
http://en.wikipedia.org/wiki/Double_dispatch
http://en.wikipedia.org/wiki/Visitor_patternand probably a more relevant:
http://en.wikipedia.org/wiki/Decorator_pattern
thanks,
Jim Langston wrote:
Any suggestions on how to improve the design?The correct answer, as aiouua said, is to use the decorator pattern.
Anyway, I wanted to point out that even with your design you don''t need
any friend function. Consider this:
#include <iostream>
#include <string>
#include <functional>
class Base
{
private:
void Walk();
void Fly();
void Swim();
void Float();
public:
Base( int X, const std::string Movement ): Move_( NULL ), X(X)
{
if ( Movement == "Flies" )
Move_ = std::mem_fun_ref(&Base::Fly);
else if ( Movement == "Walks" )
Move_ = std::mem_fun_ref(&Base::Walk);
else if ( Movement == "Swims" )
Move_ = std::mem_fun_ref(&Base::Swim);
else if ( Movement == "Floats" )
Move_ = std::mem_fun_ref(&Base::Float);
else
Move_ = std::mem_fun_ref(&Base::Walk);
}
void Move() { Move_(*this); }
private:
std::mem_fun_ref_t<void, BaseMove_;
int X;
};
void Base::Walk()
{
X += 5;
std::cout << "Walked to " << X << "\n";
}
void Base::Fly()
{
X += 7;
std::cout << "Flew to " << X << "\n";
}
void Base::Swim()
{
X += 3;
std::cout << "Swam to " << X << "\n";
}
void Base::Float()
{
X += 2;
std::cout << "Floated to " << X << "\n";
}
int main()
{
Base MyBase( 10, "Flies" );
MyBase.Move();
std::string wait;
std::getline( std::cin, wait );
return 0;
}
As already said, it;s better to decorate, having a Base with
virtual Move() = 0;
and each derived class implement a different Move().
Regards,
Zeppe
这篇关于OOP在C ++中这样做的方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!