Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/146.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 从父类调用派生类方法';同样的方法_C++_Object_Networking_Polymorphism_Derived Class - Fatal编程技术网

C++ 从父类调用派生类方法';同样的方法

C++ 从父类调用派生类方法';同样的方法,c++,object,networking,polymorphism,derived-class,C++,Object,Networking,Polymorphism,Derived Class,我的问题如下:我正在编写服务器和客户机之间的可扩展通信协议。需要传输的对象正在使用 以下是课程格式: class命令{ 公众: 使用id=uint8\u t; 使用buffer=std::vector; enum command_t:id{a_command,另一个_command}; command()=删除; 命令(id):id_u3;(id){} 静态命令*取消序列化(缓冲区); 虚拟缓冲区常量序列化()常量=0; 虚空执行()=0; 受保护的: /*不可能,请看我的进一步解释。请将其保存

我的问题如下:我正在编写服务器和客户机之间的可扩展通信协议。需要传输的对象正在使用

以下是课程格式:

class命令{
公众:
使用id=uint8\u t;
使用buffer=std::vector;
enum command_t:id{a_command,另一个_command};
command()=删除;
命令(id):id_u3;(id){}
静态命令*取消序列化(缓冲区);
虚拟缓冲区常量序列化()常量=0;
虚空执行()=0;
受保护的:
/*不可能,请看我的进一步解释。请将其保存在此处
我的例子*/
虚拟静态命令*do_unserialize(buffer::iterator,buffer::iterator)=0;
身份证;
};
甲级指挥部;
类另一个_命令;
每个命令都是
command
的子类。一个
命令\u t
id将与每个命令相关联。在上面的示例中,
a_命令
另一个_命令
也将具有相应的类

command::serialize
在派生类中实现。它所做的是将类的所有必要信息写入一个字节数组并返回。当然,对于受保护的
命令::do_unserialize
,情况也一样-它接受一个字节数组并将其转换为正确类型的命令。但问题是:

缓冲区的第一个字节将始终是与good子类关联的
命令::id
。 当服务器/客户机接收数据时,它将读取命令ID,然后需要能够将其取消序列化为正确的命令类型。这就是为什么它需要调用静态函数
command::unserialize
,而不是其中一个子类的
do\u unserialize


一个快速而肮脏的解决方案是一个如下所示的
命令::取消序列化

command*命令::取消序列化(缓冲区b){
自动输入{b.begin()};
command::id const id{*it++};
开关(静态_转换(id)){
case命令::command_t::a_命令:
返回一个命令::do_unserialize(it,b.end());
case命令::命令\u t::另一个\u命令:
返回另一个命令::do_unserialize(it,b.end());
违约:
抛出std::无效的_参数(“command::unserialize:未知命令ID”);
}   
}
***实际上甚至不是,您不能拥有虚拟静态成员函数。所以我不知道该如何实施

即使它成功了,也不是很有趣,因为它意味着必须复制一行代码 对于创建的每个新命令

编辑:一个工作示例是将
do_unserialize
移动到子类构造函数,并返回指向新创建对象的指针

class派生的_命令:public命令{
公众:
派生的_命令(buffer::iterator beg,buffer::iterator end){
//逻辑是否非序列化
}
};
//非序列化
开关(id){
case命令::命令_t::派生_类:返回新的派生_类(b.begin(),b.end());
}
// ...

因此,我的问题是:是否有一种方法可以仅从
command::id
字段动态链接新命令?一种从ID推断要使用的子类的方法?否则,我的设计有缺陷吗?有没有更好的方法来做我想做的事


谢谢大家!

你一定要修改你的设计<代码>静态函数永远不可能是虚拟的/纯虚拟的。我知道,我之所以把它放在这里,是因为这是我展示一个例子的唯一方式,可以很好地解释我要实现的目标。正如我所说的,这不是我想要的方式,我正在寻找一种更好的(在这种情况下是可行的)方式,你可以制作一个类似工厂方法的东西,在给定ID的情况下,调用适当的非序列化函数。如果您不想用一个大的switch语句来实现这一点,那么可以包含一个注册函数,不同的类将在其中传入它们的ID,以及一个指向要调用的函数的指针,以对该类型进行非序列化。我将
command
command
解析器分离
parser
将有一个
parse_command
成员,该成员将从缓冲区解析命令id并返回具体命令类的实例(当然,它类似于factory,在解析算法上具有更大的灵活性)。您的
命令
将永远不必使用缓冲区,相反,
解析器
将为您处理该缓冲区。@1201程序我想我可以去工厂,我没有想过。然而,在不添加任何内容的情况下,我认为一种更简单的方法是按照我在编辑中添加的内容(即缓冲区构造函数)进行操作。不过,工厂肯定会更灵活