简体   繁体   中英

default value of const reference parameter

Currently I have two functions:

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

void foo() {
  ...
  result = ...
  bar(result);
}

All code in foo() are the same except 1 .

Can I merge them to one function like following?

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

Btw, the parameter has to be a reference as I would like to keep the interface unchanged.

You can use the Null Object Pattern .

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. A reference is always an alias for a real object (assuming you don't trigger undefined behavior). You can achieve similar behavior without code duplication by accepting a pointer instead:

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);
}

In the spirit of DRY , why not merge them as such?

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

void foo() {
  ...
  ...
}

The entire idea of using reference is that you avoid the NULL pointer issue. The reference nothing but an alias for the real object. I have an another simple idea for your program, basically you want to achieve two functionality with same function - using default parameters. Here is the code. Please excuse me for the variable names.

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();
}

Here is the output.

The A WAS ZERO
THE A isn't zero

Use a base class that provides an interface, and two derived classes that implement the interface, one using A and the other using nothing.

Refactor foo to use a common 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);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM