【问题标题】:Mixing pointers and references in function definition in C++ [closed]在 C++ 中的函数定义中混合指针和引用 [关闭]
【发布时间】:2015-10-26 18:27:40
【问题描述】:

我有一个函数,它有两个类实例作为参数:

void cookPasta(const Tomato& tomato, const Meat* meat)
{
    if (meat != nullptr)
        cookPastaWithMeat(tomato, *meat);
    else
        cookPastaWithoutMeat(tomato);
}

如函数所示,Tomato 的实例始终是必需的,而Meat 是可选的,可以传递nullptr。我这样做是为了允许调用 cookPasta 函数,即使用户从未声明过 Meat 类的实例。

在函数签名中混合引用和指针是不好的做法吗?

【问题讨论】:

  • 如果两个参数都是指针,那么对函数的用户来说可能会更容易一些,但是编译器不会强制你第一个参数是非空的。
  • @PSkocik。这将包括在我的函数中进行额外的错误检查。你认为这比混合指针和引用更可取吗?
  • “我有一个函数有两个类作为参数”不,你没有。
  • @Chiel:我认为最好不要混合它们,并且根本不要有这个功能。有两个cookPasta 超载,一个吃番茄和肉,另一个只吃番茄。不要将可空性用于流量控制。
  • @LightnessRacesinOrbit。谢谢,使用空指针进行流量控制有什么危险?

标签: c++ oop pointers reference


【解决方案1】:

这是一种很好的做法,因为您有充分的理由这样做:指针可以nullptr,而必须始终传递引用。您正在优雅地利用这一点。

使用const表示函数不能修改调用者传来的参数;这也不错。

【讨论】:

  • 这并不优雅。您正在混合对象的间接级别,这些对象在语义上都将被视为 它们的基础对象而不是句柄。对称性被打破并产生惊喜。
  • 对称不过是物理学家不合理地渴望的理想主义。
【解决方案2】:

这种方法丢失的一件事是可能会传入一个临时的Meat,因为它的地址不能被占用。

为什么不使用重载,只需重命名cookPastaWithMeatcookPastaWithoutMeat

void cookPasta(const Tomato& tomato, const Meat& meat);
void cookPasta(const Tomato& tomato);

【讨论】:

  • 我从不相信匿名肉:太像凌晨 3 点的烤肉串。但这是一个很好的观点。
  • @Bathsheba 你是一只难缠的猫:p
  • 在这种情况下,重载相对于可选参数的优势是什么?
  • @Chiel cookPasta(tomato, Meat{}) 将编译。我会说它看起来也更惯用,但这可能是个人喜好。
  • 这是很好的做法。
【解决方案3】:

你的做法很好

  • 您使用了const 关键字。
  • 传递参考
  • 但是,第二个参数 pointer 使用 C++ 的 optional parameter feature 可能会好一些。 check out here.

    void cookPasta(const Tomato& tomato, Meat* meat = nullptr)
    {
        if (meat != nullptr)
            cookPastaWithMeat(tomato, *meat);
        else
            cookPastaWithoutMeat(tomato);
    }
    


现在,以两种方式调用相同的函数。

cookPasta(tomato); // meat will default to nullptr
cookPasta(tomato, meat);

【讨论】:

  • 除非你不能在不破坏对称性的情况下“双向”调用相同的函数。你可能是指cookPasta(tomato, &meat);,假设调用点的类型是合理的。你现在明白为什么这是不是好的做法了吗?
猜你喜欢
  • 2016-03-13
  • 1970-01-01
  • 1970-01-01
  • 2013-10-14
  • 2017-04-07
  • 1970-01-01
  • 1970-01-01
  • 2013-09-17
  • 2018-12-28
相关资源
最近更新 更多