16

I'm refactoring a large amount of code where I have to add an extra parameter to a number of functions, which will always have a value of a member of that object. Something like

class MyClass
{
public:
   CMyObject A,B;

   void MyFunc(CMyObject &Object);
   // used to be void MyFunc();
};

Now, I'd actually like it to read

class MyClass
{
public:
   CMyObject A,B;

   void MyFunc(CMyObject &Object = A);
};

But I'm not allowed to have a default parameter that is a non-static member. I've read this similar question which suggest this isn't possible, but I'm wondering if there is any reasonable workaround. Reason being that 95% of the time the default parameter will be used, and thus using a default parameter would hugely reduce the amount of code I have to change. My best solution so far is something like this;

class MyClass
{
public:
   CMyObject A,B;

   void MyFunc(BOOL IsA = TRUE);
};

void MyClass::MyFunc(BOOL IsA)
{
    CMyObject &Object = A;
    if (!IsA)
        Object = &B;
}

This is less than elgant, but is there a better way of doing this that I'm missing?

Edit: FWIW, the reason for the extra parameter is to externalize some state related members from the object in question to aid multi-threading.

Community
  • 1
  • 1
SmacL
  • 22,555
  • 12
  • 95
  • 149

2 Answers2

21

How about :

class MyClass
{
public:
   CMyObject A,B;

   void MyFunc()
   { 
     MyFunc(A); 
   }
   void MyFunc(CMyObject &Object);
};

?

Benoît
  • 16,798
  • 8
  • 46
  • 66
  • Thanks Benoit, i knew there had to be a better way. Staring at the screen too long. – SmacL Feb 19 '10 at 12:28
  • You're welcome. Note that overloads aren't allowed in C# and Java, and this is the way to compensate. So I guess i haven't invented anything :-) – Benoît Feb 19 '10 at 14:40
  • I think you mean default parameters aren't allowed in C# and Java - they certainly allow overloads (and default parameters are apparently in C# 4.0) – Michael Burr Feb 19 '10 at 15:18
  • 1
    I think the only problem with this would be if the default parameter A changes and we have to pass, let's say, C. Then either you've to update A before calling any MyFunc() or call MyFunc(C) everywhere instead of MyFunc() – sabertooth1990 Jul 22 '15 at 05:03
4

Another way:

class MyClass
{
public:
   MyObject A,B;

   void MyFunc(MyObject MyClass::*myObject = &MyClass::A) {
       MyObject& obj = *(this->*myObject);
   }
};

This makes it even impossible to pass in an MyObject member from another MyClass instance. Your three valid options to call MyFunc are .MyFunc(), .MyFunc(&MyClass::A) and .MyFunc(&MyClass::B)

MSalters
  • 173,980
  • 10
  • 155
  • 350