const引用形参的默认值

default value of const reference parameter

本文关键字:默认值 形参 引用 const      更新时间:2023-10-16

目前我有两个函数:

void foo(const A & a) {
  ...
  result = ...
  result += handle(a); // 1
  bar(result);
}
void foo() {
  ...
  result = ...
  bar(result);
}

foo()中的所有代码都是相同的,除了1

我可以像下面这样把它们合并成一个函数吗?

void foo(const A & a = 0) {
  ...
  ...
  if (a) result += handle(a); // this won't work, but can I do something similar?
  bar(result);
}

顺便说一句,参数必须是一个引用,因为我想保持接口不变。

可以使用空对象模式

namespace
{
  const A NULL_A; // (possibly "extern")
}
void foo(const A & a = NULL_A) {
  ...
  result = ...
  if (&a != &NULL_A) result += handle(a);
  bar(result);
}

No。引用总是真实对象的别名(假设您没有触发未定义行为)。您可以通过接受指针来实现类似的行为,而无需重复代码:

void foo_impl(A const* obj) {
    // code as before, except access obj with -> rather than .
}
void foo (A const& obj) {
    foo_impl(&obj);
}
void foo() {
    foo_impl(nullptr);
}

在DRY的精神下,为什么不这样合并它们呢?

void foo(const A & a) {
  foo();
  handle(a);
}
void foo() {
  ...
  ...
}

使用引用的全部思想是避免NULL指针问题。引用只不过是真实对象的别名。我对你的程序有另一个简单的想法,基本上你想用相同的函数实现两个功能-使用默认参数。下面是代码。请原谅变量的名称。

class ABC
{
public:
    int t;
     ABC operator=(ABC& other)
    {
        other.t = 0;
    }
};
ABC other;

void foo( ABC &a=other);
void foo( ABC &a)
{
   if( a.t == 0)
       qDebug()<<"The A WAS ZERO";
   else
       qDebug()<<"THE A isn't zero";
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    ABC hello;
    hello.t = 100;
     foo();
     foo(hello);

    return a.exec();
}

下面是输出。

The A WAS ZERO
THE A isn't zero

使用提供接口的基类和实现接口的两个派生类,一个使用A,另一个不使用任何东西。

重构foo,使用一个通用的foo

struct Handler
{
   virtual int get() = 0;
};
struct AHandler : Handler
{
   AHandler(const A& a) : a_(a) {}
   virtual int get() { return handle(a_); }
   const A& a_;
}
struct NullHandler : Handler
{
   virtual int get() { return 0; }
}
void foo(const Handler & h) {
  ...
  result = ...
  result += h.get();
  bar(result);
}
void foo(const A & a) {
    AHandler ah(a);
    foo(ah);
}
void foo() {
    NullHandler nh(a);
    foo(nh);
}