O_o
To much hassle... just dropping some notes and code.
If you are not overriding the behavior allow the declaration of the inherited function to be inherited. (Do not declare the function again in a derived class unless you need to do so for other reasons.)
Code:
class B
{
public:
virtual void Foo( int x, int mode = 7)
{
}
};
class C : public B
{
public:
//virtual void Foo( int x, int mode );
};
int main()
{
C a;
a.Foo(0);
return(0);
}
If you need to override the behavior, use the same declared default value for ever parameter that you need.
Code:
class B
{
public:
virtual void Foo( int x, int mode = 7)
{
}
};
class C : public B
{
public:
virtual void Foo( int x, int mode = 7)
{
}
};
int main()
{
C a;
a.Foo(0);
return(0);
}
I hate this method because the default value can get out of sync. (If the default value is out of sync you violate "is-a" and the more appropriate "constrained-as".) You can go a more robust route by changing them both at the same time by using a separate value to store the default value.
Code:
class B
{
public:
virtual void Foo( int x, int mode = default_mode)
{
}
static const int default_mode = 7;
};
class C : public B
{
public:
virtual void Foo( int x, int mode = default_mode)
{
}
};
int main()
{
C a;
a.Foo(0);
return(0);
}
However, this too has problems in a header only distribution. (This I believe is fixed in "C++0X".) You may instead use a function with the short interface forwarding to the implementation of the long interface. (Exactly as you've done, you just need to do it appropriately.)
As with the other path, you should not use a declaration in the derived class unless you need to override the behavior.
Code:
class B
{
public:
virtual void Foo( int x)
{
this->Foo(x, 7);
}
virtual void Foo( int x, int mode)
{
}
};
class C : public B
{
public:
//virtual void Foo( int x, int mode);
};
int main()
{
C a;
a.Foo(0);
return(0);
}
If you do need to override the behavior, the implementation, you must tell the compiler that the both functions, the short interface and the implementation interface, are available to the derived class.
You should be careful with this path because it is easy to fall into the trap of only declaring the inherited short interface function. (I've included it for the sake of completeness. It is the following example.) This approach will fail to compile for various reasons.
Code:
class B
{
public:
virtual void Foo( int x)
{
this->Foo(x, 7);
}
virtual void Foo( int x, int mode)
{
}
};
class C : public B
{
public:
virtual void Foo(int x);
virtual void Foo( int x, int mode)
{
}
};
int main()
{
C a;
a.Foo(0);
return(0);
}
On failing with that you will probably implement the forwarding functions in the derived class--the same as you've done in the base class.
Code:
class B
{
public:
virtual void Foo( int x)
{
this->Foo(x, 7);
}
virtual void Foo( int x, int mode)
{
}
};
class C : public B
{
public:
virtual void Foo(int x)
{
this->Foo(x, 7);
}
virtual void Foo( int x, int mode)
{
}
};
int main()
{
C a;
a.Foo(0);
return(0);
}
This approach is fine in some cases. (Which is why I've included the approach.) But it can be tedious and error prone, and with multiple derived classes the overhead becomes a serious problem.
In most cases you will only tell the compiler to use the functions from the derived class with a using declaration.
Code:
class B
{
public:
virtual void Foo( int x)
{
this->Foo(x, 7);
}
virtual void Foo( int x, int mode)
{
}
};
class C : public B
{
public:
using B::Foo;
virtual void Foo( int x, int mode)
{
}
};
int main()
{
C a;
a.Foo(0);
return(0);
}
Just for the sake of information, both approaches will violate the requirements and standard practices of many code houses so you should have a good reason to require the behavior--a reason beyond "I don't want to have to remember the correct value.".
Soma