当前位置:编程学习 > C/C++ >>

关于函数返回值的设计的一些思考

作者:朱金灿

       最近对函数返回值的设计有了一些新的思考。前一阵子头检查我写的代码。我的代码大致如下(凭记忆):

 


#include <stdio.h>
#include <float.h>
#include <string>
using std::string;
#include <vector>
using std::vector;
/*! @struct stExtent
*  @brief
*
* 地理范围结构体,实现对地理范围的各种操作,如合并
*  @author zjc
*  @version 0.1
*  @date    2010.08.10
*/
struct stExtent
{
      stExtent()
   {
          m_fMinX = -FLT_MAX;
          m_fMaxX = FLT_MAX;
          m_fMinY = -FLT_MAX;
          m_fMaxY = FLT_MAX;
   }
   /*!
   *  @brief 合并两个地理范围
   *
   *  @param [in]Other 另一个地理范围
      *  @return 新的地理范围
   */
     stExtent operator + (stExtent &Other)
  {
    m_fMinX = std::min(m_fMinX,Other.m_fMinX);
          m_fMaxX = std::max(m_fMaxX,Other.m_fMaxX);
          m_fMinY = std::min(m_fMinY,Other.m_fMinY);
    m_fMaxY = std::max(m_fMaxY,Other.m_fMaxY);
    return *this;
  }
  void operator = (stExtent &Other)
  {
   m_fMinX = Other.m_fMinX;
   m_fMaxX = m_fMaxX,Other.m_fMaxX;
   m_fMinY = m_fMinY,Other.m_fMinY;
   m_fMaxY = m_fMaxY,Other.m_fMaxY;
  }
  /**
  * @brief X方向的最小值
  */
     float m_fMinX;
  /**
  * @brief X方向的最大值
  */
  float m_fMaxX;
  /**
  * @brief Y方向的最小值
  */
  float m_fMinY;
  /**
  * @brief Y方向的最大值
  */
     float m_fMaxY;
};
/*! @class CDrawObj
*  @brief
*
*  显示对象基类
*  @author zjc
*  @version 0.1
*  @date    2010.08.10
*/
class CDrawObj
{
public:
 CDrawObj()
 {
   m_Extent.m_fMinX = 0.0f;
   m_Extent.m_fMinY = 0.0f;
   m_Extent.m_fMaxX = 100.0f;
   m_Extent.m_fMaxY = 100.0f;
 }
  
 /*!
 *  @brief 获取显示对象的地理范围
 *  @return 显示对象的地理范围
 */
    stExtent& GetExtent()
 {
  return m_Extent;
 }
protected:
private:
 
 /**
 * @brief 显示属性数组
 */
 std::vector<stProperty> m_vecPropertys;
 /**
 * @brief 地理范围
 */
    stExtent m_Extent;
};
/*! @class CDrawObj
*  @brief
*
*  显示对象基类
*  @author zjc
*  @version 0.1
*  @date    2010.08.10
*/
class CDrawObj
{
public:
 CDrawObj()
 {
   m_Extent.m_fMinX = 0.0f;
   m_Extent.m_fMinY = 0.0f;
   m_Extent.m_fMaxX = 100.0f;
   m_Extent.m_fMaxY = 100.0f;
 }
  
 /*!
 *  @brief 获取显示对象的地理范围
 *  @param Extent 求取的地理范围
 *  @return 显示对象的地理范围
 */
    void GetExtent(stExtent& Extent)
 {
   Extent = m_Extent;
 }
protected:
private:
 
 /**
 * @brief 显示属性数组
 */
 std::vector<stProperty> m_vecPropertys;
 /**
 * @brief 地理范围
 */
    stExtent m_Extent;
};
 

 

 

 

      头建议我将CDrawObj类的GetExtent函数改为如下:

  stExtent& GetExtent()
 {
  return m_Extent;
 }
 


我说:"这样是为了方便实现链式表达式吗?"我的意思是:照头的改法,外部可以这样调用:stExtent TmpExtent = Obj1. GetExtent() + Obj1. GetExtent();头说:"不完全是,你想照你的做法,用户必须先定义一个stExtent变量,再把它传进函数。"我说:"这源于我的习惯认识,我认为renturn 返回的值用于判断操作是否成功"。不过这次头确实说的有道理,因为这个操作的返回值是void,那么直接返回操作结果值更为合理。

 


     今天见到这样一个类的函数这样写:

struct stProperty
{
     stProperty()
  {
    m_strName = _T("");
  }
  /**
  * @brief 显示属性名
  */
  std::string m_strName;
};
  /*!
 *  @brief 给出一个属性名字,查找这个属性
 *
 *  @param [in]strProName 给定的属性名字
 *  @return 属性
 */
    stProperty Invalid_Property;
 stProperty SearchProperty(const std::string strProName) const
 {
      //m_vecPropertys为一个类的属性数组先循环属性数组,找出符合条件的数组,
  // 若不存在,抛出异常并返回错误属性
  try
  {
   for (size_t i =0;i<m_vecPropertys.size();i++)
   {
    if (strProName==m_vecPropertys[i].m_strName)
    {
     return m_vecPropertys[i];
    }
   }
  }
  catch (...)
  {
  }
  throw _T("cannot find Property");
  return Invalid_Property;
 }
 

 

       我觉得这样设计并不合理,如果让我设计的话,我会这样设计这个函数:
BOOL SearchProperty(const std::string strProName,stProperty &prop),
用BOOL变量返回值来判断是否存在这样的属性,用变量prop来保存查找结果。

 


       为此我总结了一下设计函数的一些心得:首先判断是否需要操作是否成功、值是否存在,若不需要,考虑直接返回操作结果(即由renturn语句返回而不是通过输出参数返回),毕竟这样外部调用比较方便,若需要,则应设计为通过输出参数返回操作结果值。

补充:软件开发 , C语言 ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,