【问题标题】:Assign value to pointer if not null如果不为空,则为指针赋值
【发布时间】:2014-07-31 18:57:12
【问题描述】:

我有一个整数指针作为默认函数参数。如果它不为空,我想分配一些值,也许每 200 行中的第 10 行。通过在每次分配之前进行标准检查,我的代码很容易变得庞大且难以阅读。 (我指的是源文件长度和可读性,而不是二进制大小。)

替换这个是好习惯吗:

// Previous statement
// Use to put empty line here
if(ptr)
    *ptr = val;
// Empty line also here
// Next statement

用这个:

// Previous statement
assignIfNotNull(ptr, val);
// Next statement

并把 if 放入函数中?

inline void assignIfNotNull(int *ptr, int val)
{
    if(ptr)
        *ptr = val;
}

现在,我似乎很细致,但这每次使用会节省 3 行。也许不是我编程风格中最糟糕的事情,这是我独自学习时即兴创作的。我想压制它,询问并跟上标准。 (我在任何地方都找不到这个。)

提前致谢。

【问题讨论】:

  • 第二版错误。您正在通过值传递指针,您需要一个双指针或通过引用传递指针。
  • @40two 赋值为 *ptr = ...,没关系
  • @DieterLücking 道歉没有注意到 :( 请忽略我的评论 Dieter 是对的。
  • 我个人不会这样做,因为 API 不会得到太多使用。我宁愿编写更严格的代码,当我输入一段我知道指针应该有效的代码时跳过任何检查,而不是使用 API 来设置不断进行不必要检查的值。
  • 如果不支持某些编辑工具,assignIfNotNull 需要比 if 版本更多的输入。除此之外,它是一个纯粹的便利功能。即使有一个好名字,你也必须在使用它之前查找(知道)函数(我不会这样做,除非它在某些源文件中本地使用)

标签: c++ pointers null


【解决方案1】:

你可以去:

T dummy;
if ( !ptr ) 
    ptr = &dummy;

一开始;然后你就可以放心地写*ptr = whatever;,而不需要空检查。

如果ptr 的原始值很重要,你可以调用参数orig_ptr 之类的。

【讨论】:

    【解决方案2】:

    C# null coalescing operator equivalent for c++ 几乎准确地提出了您的问题,但不要指望找到一些突破性的解决方案 - 三元运算符、模板和宏只有一些变化:

    ptr = (ptr != null ? ptr : MY_DEFAULT)
    
    //------------------- or as function
    template<class T>
    GetValueOrDefault(T* value, T* defaultValue) // or put your own types
    {
        return value != null ? value : defaultValue;
    }
    
    ptr = GetValueOrDefault(ptr, MY_DEFAULT);
    
    //------------------- or as macro
    
    #define GET_VALUE_OR_DEFAULT(value, defaultValue) (value != null ? value : defaultValue)
    
    ptr = GET_VALUE_OR_DEFAULT(ptr, MY_DEFAULT);
    
    //------------------- or like this macro
    
    #define VALUE_OR_DEFAULT(value, defaultValue) value = (value != null ? value : defaultValue)
    
    VALUE_OR_DEFAULT(ptr, MY_DEFAULT);
    

    但有几点你应该考虑:

    1. 当问题不存在时不要想像 - 很多检查和重新初始化对于某些 API 是完全可行的 - 看看 WINAPI
    2. 您确定要覆盖该变量吗?可能是你 可以重写您的函数或 API 以不覆盖它。
    3. 您也可以考虑使用一些临时变量来代替 ptr - 解决不了问题,把它倒过来,但是 这可能会提高您的整体可理解性 功能和删除检查:

        char* tempPtr = ptr;
        retCode = RandomlyNullifyThePtr(&tempPtr); // RandomlyNullifyThePtr can nullify the ptr it gets ,
        // but it won't nullify the ptr in calling function.
      
    4. 如果您在保存整个函数时遇到问题 良心那么直接的迹象表明它应该被重构 - 分成更小的部分,这样的检查可能会变成 不必要的:

        retCode = CompletePart1(ptr); // CompletePart1 can nullify the ptr it gets, 
        // but it won't nullify the ptr in calling function.
        ...
        retCode = CompletePart2(ptr);
      

    【讨论】:

    • 另一个考虑是使用引用而不是指针。通过引用,可以保证对象存在。一个指针可以指向一个无效的位置并且仍然是非零或非空的。
    猜你喜欢
    • 2019-07-10
    • 1970-01-01
    • 2023-04-10
    • 2011-01-20
    • 2010-09-11
    • 2019-02-09
    • 1970-01-01
    • 2018-05-03
    • 2019-11-05
    相关资源
    最近更新 更多