静态与静电之间动态多态... [英] Between static & dynamic polymorphism...

查看:83
本文介绍了静态与静电之间动态多态...的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我只是想把它扔到这里以防万一比我聪明的人

a建议/解决方法:


问题:


我有一个经典的生产者/消费者系统,它接受来自

a socket的''命令''和''执行''它们。显然,每个不同的命令(当前大约有20个b $ b)都有自己需要的功能。梦想目标

这里将删除

运行时所有关于命令性质的知识。也就是说,我不想要任何开关/箱子或者是否需要确定已收到的命令等等:


1.接受来自套接字的命令。

2.使用命令数据创建通用的''command''对象。

3.在命令对象上调用''execute''。

4.特定于命令的代码运行。


所以,有两个明显的方法是_close_:


使用static polylmorphism:


template< unsigned long commandCode>

class base_command {

void execute();

.....

};


//命令1

void base_command< 1> :: execute(){

....命令1特定代码...

}

void base_command< 2> :: execute() {

....命令2具体代码...

}


int main(){

unsigned long commandCode = //以某种方式读取命令

base_command< commandCode>()。execute( ); //显然不起作用

因为编译器在编译时不知道''commandCode'

}

使用动态多态性:


class base_command {

virtual void execute()= 0;

};


class command_1:public base_command {

virtual void execute(){

...命令1具体代码...

}

};


class command_2:public base_command {

.... etc ...

};


int main(){

unsigned long commandCode = //以某种方式读取命令

base_command * c = //确定子类的一些逻辑(巨大的

开关/案例)

}

所以,我会的喜欢使用静态多态,但我很确定这个

不可能也永远不会发生,因为没有编译时知道

命令代码。我正在实现动态方法,但是我需要确定命令类型所需的巨大开关/案例。在所有情况下,

可执行文件的大小应该相同,但我真正想要的是b)清洁度和b)效率。我正在使用嵌入式的
系统,因此使用多态性会让我感到恶心。但是,我猜这个或者是一个带有巨大if / else的课程。


我还有其他疯狂的一半 - 像构造函数映射的想法

由命令代码索引的对象(boost可能有一些坚果

可能会支持这一点)。但在大多数情况下,我认为我很难被b $ b卡住。


除非有人有任何想法...

谢谢,

瑞恩

I just wanted to throw this up here in case anyone smarter than me has
a suggestion/workaround:

Problem:

I have a classic producer/consumer system which accepts ''commands'' from
a socket and ''executes'' them. Obviously, each different command (there
are ~20 currently) has its own needed functionality. The dream goal
here would be to remove all knowledge of the nature of the command at
runtime. That is, I don''t want ANY switch/cases or if/elses to
determine what command has been received, etc:

1. Accept command from socket.
2. Create generic ''command'' object with command data.
3. Call ''execute'' on command object.
4. Command-specific code runs.

So, there''s two obvious ways that are _close_:

Using static polylmorphism:

template <unsigned long commandCode>
class base_command {
void execute();
.....
};

// command 1
void base_command<1>::execute() {
....command 1 specific code...
}
void base_command<2>::execute() {
....command 2 specific code...
}

int main() {
unsigned long commandCode = //read command in somehow
base_command<commandCode>().execute(); //obviously doesn''t work
because the compiler doesn''t know ''commandCode'' at compile-time
}
Using dynamic polymorphism:

class base_command {
virtual void execute() = 0;
};

class command_1 : public base_command {
virtual void execute() {
...command 1 specific code...
}
};

class command_2 : public base_command {
.... etc...
};

int main() {
unsigned long commandCode = // read command in somehow
base_command* c = // some logic to determine subclass from (huge
switch/case)
}
So, I''d love to use static polymorphism, but I''m fairly certain this
can''t and never will happen, due to no compile-time knowledge of the
command code. I''m currently implementing the dynamic method, but I
HATE the huge switch/case needed to determine command type. The
executable size should be the same in all cases, but what I''m really
looking for is a) cleanliness and b) efficiency. I''m on an embedded
system, so using polymorphism makes me sick to my stomach. But, I
guess it''s either that or one class with an enormous if/else.

I''ve got some other crazy half-ideas like a map of constructor function
objects indexed by command code (boost probably has something nutty
that might half-support this). But for the most part I think I''m
stuck.

Unless anyone has any thoughts...
Thanks,
Ryan

推荐答案

rwf_20写道:
我只是想把它扔到这里以防万一比我聪明的人有建议/解决方法:

问题:

我有一个经典的生产者/消费者系统接受''命令''来自
一个套接字并''执行''它们。显然,每个不同的命令(当前大约有20个)都有自己需要的功能。梦想的目标
这将是在运行时删除所有关于命令性质的知识。也就是说,我不想要任何开关/箱子或者/或者等等来确定收到的命令等等:
I just wanted to throw this up here in case anyone smarter than me has
a suggestion/workaround:

Problem:

I have a classic producer/consumer system which accepts ''commands'' from
a socket and ''executes'' them. Obviously, each different command (there
are ~20 currently) has its own needed functionality. The dream goal
here would be to remove all knowledge of the nature of the command at
runtime. That is, I don''t want ANY switch/cases or if/elses to
determine what command has been received, etc:




查找 ;对象工厂在网上获得现代C ++设计

Alexandrescu。或者只是定义一个std :: map< id,function_pointer> ;.

Jonathan



Look up "object factory" on the web and get Modern C++ Design by
Alexandrescu. Or simply define a std::map<id, function_pointer>.
Jonathan


或者使用boost :: function< void (param_t)> ;.


示例:


typedef boost :: function< void(void)> ConsumerCommand;

ConsumerCommand cmd;

bool gotIt = consumerQueue.getNext(cmd);

if(gotIt)cmd();

Alternatively use boost::function<void (param_t)>.

Example:

typedef boost::function<void (void)> ConsumerCommand;
ConsumerCommand cmd;
bool gotIt = consumerQueue.getNext(cmd);
if(gotIt) cmd();




rwf_20写道:

rwf_20 wrote:
我只想把它扔到这里以防万一比我聪明的人
建议/解决方法:
I just wanted to throw this up here in case anyone smarter than me has
a suggestion/workaround:



我不知道我是不是更聪明,那就是(更聪明的是什么)......

但是


你需要相互抽象动态和静态多态。

你希望能够使用动态多态来通过一个

接口,但静态多态来调用特定的东西(我不知道这是否有意义)。


你永远不能将命令的发送者绑定到接收器类型,因为它可能想要将msgs发送到任意接收器。出于这个原因,你的

基数应该使用动态多态(我会简短)。


struct BaseCmd

{

void execute()= 0;

BaseCmd * clone()const = 0; //我知道更好的克隆实现

:-)

};


class Client //去打电话给Cmd。执行

{

void associate(const BaseCmd& cmd){cmd_ = cmd.clone(); }

// ...

BaseCmd * cmd_;

};


模板< ;类T>

类MyCmd:public BaseCmd

{

//实现执行。

};


现在我们通过创建一个代表所有类型T'的命令获胜,但

客户端无视,因为BaseCmd不依赖于类型。通过抽象动态和静态部件来赢取两种方式。


有关更多信息,您还可以参考Herb Sutters文章

优雅的函数调用包装器。


亲切的问候,


Werner


I don''t know whether I''m smarter, thats (smarter in terms of what)...
but

You need to abstract dynamic and static polymorphism from each other.
You want to be able to use dynamic polymorphism to execute via one
interface, but static polymorphism to call something specific (I don''t
know whether this makes sense).

You can never bind the sender of your command to a receiver type, as it
may want to send msgs to arbitrary receivers. For this reason, your
base should use dynamic polymorphism (I''ll be brief).

struct BaseCmd
{
void execute() = 0;
BaseCmd* clone() const = 0; //I know of better clone implementations
:-)
};

class Client //Going to call Cmd.execute
{
void associate( const BaseCmd& cmd ){ cmd_ = cmd.clone(); }
//...
BaseCmd* cmd_;
};

template <class T>
class MyCmd : public BaseCmd
{
//Implements execute.
};

Now we win by creating 1 command that represents all type T''s, but
Client is oblivious as the BaseCmd is not type dependent. Winning both
ways by abstracting dynamic and static parts.

For more information, you can also refer to Herb Sutters article
"Elegant function call wrappers".

Kind regards,

Werner


这篇关于静态与静电之间动态多态...的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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