搜狗workflow——C++并行计算与异步网络引擎 序列化与反序列化 代码分析(二)

魏勇军
2023-12-01

2021SC@SDUSC

目录

一.前置知识

二.具体代码分析


一.前置知识

1.  size_t: size_t是一些C/C++标准在stddef.h中定义的,size_t 类型表示C中任何对象所能达到的最大长度,它是无符号整数(在默认情况下声明的整型变量都是有符号的类型 除了char有点特别)。

2.错误代码:

人们在使用软、硬件的时候,软、硬件不能正常操作。由于错误的类型很多,为了对错误进行区分,系统设定了错误代码(error code),软、硬件在运行中如果发生错误,将通过它内部的原有的设定判断、识别而通过错误代码的显示方式给操作者,操作者通过错误代码识别,快速找到软、硬件不能正常操作的具体原因。

错误代码即为在程序运行过程中,我们给不同类型的错误设定的一个唯一的编号,便于进行错误排除。

代码中出现的错误代码是

ENOTTY

25

Not a tty device

3.关于内部类:

所谓内部类就是在一个类内部进行其他类结构的嵌套操作。

优点有:

  1. 内部类与外部类可以方便的访问彼此的私有域(包括私有方法、私有属性)。
  2. 内部类是另外一种封装,对外部的其他类隐藏。

二.具体代码分析

协议的实现----头文件代码分析

namespace protocol
{

class ProtocolMessage : public CommMessageOut, public CommMessageIn
{
protected:
    virtual int encode(struct iovec vectors[], int max)
    {
        errno = ENOSYS;
        return -1; 
    } 

关于iovec的返回值:(1) 成功,返回读写的字节数,这个字节数是所有iovec结构中iov_len的总和;(2)失败返回-1,并设置好errno。

   接下来,我们必须实现一个“append”函数,建议使用带有参数“size_ t *size”的第一个函数

    参数“size”表示要追加的字节,并返回使用的字节.

 
    virtual int append(const void *buf, size_t *size)
    {
        return this->append(buf, *size);
    }

这是正常返回的情况;

 
    virtual int append(const void *buf, size_t size)
    {
        errno = ENOSYS;
        return -1;
    }

这是失败的情况。  

public:
    void set_size_limit(size_t limit) { this->size_limit = limit; }
    size_t get_size_limit() const { return this->size_limit; }

公开定义一个方法set_size_limit

const修饰的数据类型是指常类型,常类型的变量或对象的值是不能被更新的。

public:
    class Attachment
    {
    public:
        virtual ~Attachment() { }
    };

定义一个内部类,并注意在基类的析构函数前面加上virtual,使其变成虚析构在C++程序中使用虚函数,虚继承和虚析构是很好的习惯 可以避免许多的问题。

“~”为位运算,含义为取反。

    void set_attachment(Attachment *att) { this->attachment = att; }
    Attachment *get_attachment() const { return this->attachment; }

protected:
    virtual int feedback(const void *buf, size_t size)
    {
        if (this->wrapper)
            return this->wrapper->feedback(buf, size);
        else
            return this->CommMessageIn::feedback(buf, size);
    }

用protected 修饰成员变量为保护类型,可以被所在类的子类所访问。protected修饰的变量和方法,允许在同一个类中访问、同一个包中访问;虚方法feedback中定义了一个常指针buf,和无符号整数size。如果指向weapper构造器,则以构造器的方面返回;反之,则以类继承的CommMessageIn中的feedback方法返回。

protected:
    size_t size_limit;

private:
    Attachment *attachment;
    ProtocolMessage *wrapper;

用  Attachment类定义一个指针*attachment;

用   ProtocolMessage定义一个指针 *wrapper。

public:
    ProtocolMessage()
    {
        this->size_limit = (size_t)-1;
        this->attachment = NULL;
        this->wrapper = NULL;
    }

    virtual ~ProtocolMessage() { delete this->attachment; }

给size_limit,attachment,wrapper三个变量赋初值;

在回来的时候到delete基类指针时,继承树上的析构函数会被自低向上依次调用,即最底层派生类的析构函数会被首先调用,然后一层一层向上直到该指针声明的类型,删除掉this->attachment。

public:
    ProtocolMessage(ProtocolMessage&& msg)
    {
        this->size_limit = msg.size_limit;
        msg.size_limit = (size_t)-1;
        this->attachment = msg.attachment;
        msg.attachment = NULL;
    }

给size_limit,attachment赋初值;其中attachment为NULL。

    ProtocolMessage& operator = (ProtocolMessage&& msg)
    {
        if (&msg != this)
        {
            this->size_limit = msg.size_limit;
            msg.size_limit = (size_t)-1;
            delete this->attachment;
            this->attachment = msg.attachment;
            msg.attachment = NULL;
        }

        return *this;
    }

重载运算符“=”;当msg的地址不等于当前的地址,设置size_limit,attachment的值。

----------------------------------------------------------------

参考文献:

(44条消息) Linux错误代码:errno.h与返回值 -EINVAL_格格的博客-CSDN博客_einval

Linux错误代码含义/Linux Error Code - fhefh - 博客园 (cnblogs.com)

(44条消息) 关于int main( int argc, char* argv[] ) 中arg和argv参数的解析及调试_一树荼蘼的博客-CSDN博客

src/protocol/ProtocolMessage.h · 搜狗开源/workflow - Gitee.com

 类似资料: