zoukankan      html  css  js  c++  java
  • Linux环境高级编程--出错处理(CLStatus)

              非常多程序库对外提供若干类,每一个方法出错时怎样告知调用者是否出错,以及出错码(在Linux上在error.h中的全局errno就是保存我们Linux程序运行的出错码的)?方法非常多,为了简化起见,函数将返回一个对象,该对象保存了函数的返回值和出错码。

    /*
     * 	CLStatus.h
     *
     *      Author: lilin
     *      email: 	lilin@uestc.edu.cn
     */
    #ifndef CLSTATUS_H
    #define CLSTATUS_H
    
    //用于保存函数的处理结果
    class CLStatus
    {
    public:
    	/*
    	lReturnCode >=0表示成功。否则失败
    	*/
    	CLStatus(long lReturnCode, long lErrorCode);
    	CLStatus(const CLStatus& s);
    	virtual ~CLStatus();
    
    public:
    	bool IsSuccess();
    
    public:
    	/*通过这样能够是m_lErrorCode和m_lReturnCode做为public
    	成员隐藏了写。但能够公开了读*/
    	const long& m_clReturnCode;
    	const long& m_clErrorCode;
    
    private:
    	//返回值
    	long m_lReturnCode;
    	//出错码
    	long m_lErrorCode;
    };
    
    #endif
    
    #include "CLStatus.h"
    
    CLStatus::CLStatus(long lReturnCode, long lErrorCode) : m_clReturnCode(m_lReturnCode), m_clErrorCode(m_lErrorCode)
    {
    	m_lReturnCode = lReturnCode;
    	m_lErrorCode = lErrorCode;
    }
    
    CLStatus::~CLStatus()
    {
    }
    
    CLStatus::CLStatus(const CLStatus& s) : m_clReturnCode(m_lReturnCode), m_clErrorCode(m_lErrorCode)
    {
    	m_lReturnCode = s.m_lReturnCode;
    	m_lErrorCode = s.m_lErrorCode;
    }
    
    bool CLStatus::IsSuccess()
    {
    	if(m_clReturnCode >= 0)
    		return true;
    	else
    		return false;
    }

    当中m_lReturnCode;存储返回值,m_lErrorCode存储错误码。

    const long& m_clReturnCode;const long& m_clErrorCode;通过这样能够是m_lErrorCode和m_lReturnCode做为public成员隐藏了写,但能够公开了读。当然我们还有其它选择。提getMIReturnCode()方法来达到相同的效果。当然在这里认为通过提供get方法,而不提供set方法更符合面向对象的数据封装特性。

    (代码见github上APUEsrc/2/2.7/



    上面的代码,是不是还能够效率上是不是还能够优化呢?

    /*
     * test.cpp
     *
     *      Author: lilin
     *      email: 	lilin@uestc.edu.cn
     */
    #include <iostream>
    
    using namespace std;
    
    class A
    {
    public:
    	A()
    	{
    		cout << "In A(): " << hex << (long)this << endl;
    	}
    
    	A(const A&)
    	{
    		cout << "In A(const A&): " << hex << (long)this << endl;
    	}
    
    	~A()
    	{
    		cout << "In ~A(): " << hex << (long)this << endl;
    	}
    
    	A& operator=(const A& a)
    	{
    
    		cout << "In operator=: " << hex << (long)this << " = " << hex << (long)(&a) << endl;
    		return *this;
    	}
    };
    
    A f()
    {
    	A a;
    	return a;
    }
    
    int main(int argc, char* argv[])
    {
    	A a;
    	a = f();
    	return 0;
    }
    
    代码执行结果例如以下:

    In A(): 7fff834e277e
    In A(): 7fff834e277f
    In operator=: 7fff834e277e = 7fff834e277f
    In ~A(): 7fff834e277f
    In ~A(): 7fff834e277e
    在把代码稍稍的改动下:

    /*
     * test.cpp
     *
     *      Author: lilin
     *      email: 	lilin@uestc.edu.cn
     */
    #include <iostream>
    
    using namespace std;
    
    class A
    {
    public:
    	A()
    	{
    		cout << "In A(): " << hex << (long)this << endl;
    	}
    
    	A(const A&)
    	{
    		cout << "In A(const A&): " << hex << (long)this << endl;
    	}
    
    	~A()
    	{
    		cout << "In ~A(): " << hex << (long)this << endl;
    	}
    
    	A& operator=(const A& a)
    	{
    
    		cout << "In operator=: " << hex << (long)this << " = " << hex << (long)(&a) << endl;
    		return *this;
    	}
    };
    
    A f()
    {
    	return A();
    }
    
    int main(int argc, char* argv[])
    {
    	A a = f();
    	return 0;
    }
    在看看执行结果:

    In ~A(): 7ffff682a68f
    In ~A(): 7ffff682a68e
    明显整个过程少创建了一个对象,而且少调用了一次重载的=操作。效率是不是得到了明显的提升。可是为什么会这样呢?这里我们来看看程序究竟做了些什么?

    改动之后的代码我们实际上仅仅创建了一个对象。是在f()函数中创建的。

    而在A a=f();这行代码中。调用并非赋值运算,而是默认的拷贝构造函数,在默认的拷贝构造函数是将对象的引用直接返回过来,所以。也就仅仅创建了一个CLStatus对象。至于为什么不是调用重载的赋值运算。而是调用了默认的拷贝构造函数,能够參考 拷贝构造函数和赋值运算符差别 

    所以,为了兼顾效率和移植性,在今后我们函数的返回值都统一用CLStatus封装后在返回。并建议代码的书写方式例如以下:

    CLStatus f()
    {
    	return CLStatus(…);
    }
    CLStatus s = f();
    

    (如有不论什么疑问或建议请联系cfreestar@163.com)

    Linux环境高级编程系列博客 文件夹

    Linux环境高级编程--介绍


  • 相关阅读:
    怎样检测数据类型
    怎样理解函数参数的传递
    怎样在微信H5中点击直接跳转到公众号
    怎样启动和关闭nginx服务器
    怎样测试nginx.conf配置文件的正确性
    怎样查找/搜索文件
    怎样创建用户组并添加用户进用户组
    怎样查看Nginx版本号
    怎样写一个Hello World!
    怎样理解基本类型(原始类型)的数据和引用类型的数据
  • 原文地址:https://www.cnblogs.com/wgwyanfs/p/6872696.html
Copyright © 2011-2022 走看看