OOP在C ++中这样做的方法? [英] OOPs way to do this in C++?

查看:100
本文介绍了OOP在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



可能更相关:
http://en.wikipedia.org/wiki/Decorator_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_pattern

and 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆