Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > named parameter idiom and inheritance

Reply
Thread Tools

named parameter idiom and inheritance

 
 
Christof Warlich
Guest
Posts: n/a
 
      06-14-2012
Hi,

please consider the following code, using named parameters for object
instantiation:

class Base {
public:
Base(): _varBase(0) {}
Base &varBase(int var) {_varBase = var; return *this;}
private:
int _varBase;
};
class Derived: public Base {
public:
Derived(): _varDerived(0) {}
Derived &varDerived(int var) {_varDerived = var; return *this;}
// ugly forwarding function
Derived &varBase(int var) {varBase(var); return *this;}
private:
int _varDerived;
};
int main() {
Derived w = Derived().varDerived(42);
// the forwarding function is needed for all of these.
Derived x = Derived().varBase(4711);
Derived y = Derived().varDerived(42).varBase(4711);
Derived z = Derived().varBase(4711).varDerived(42);
}

It works fine so far, but now imagine that the classes have more
member variables and that the inheritance hierarchy is deeper than 2
(i.e. we have classes DerivedFromDerived, ...). Then, _each_ of the
derived classes would need a forwarding function for _every_ variable
in _any_ of its base classes, which doesn't scale very well.

Is anyone aware of a way to avoid these forwarding function(s)?

Thanks for any ideas,

Chris
 
Reply With Quote
 
 
 
 
Victor Bazarov
Guest
Posts: n/a
 
      06-14-2012
On 6/14/2012 3:41 AM, Christof Warlich wrote:
> please consider the following code, using named parameters for object
> instantiation:
>
> class Base {
> public:
> Base(): _varBase(0) {}
> Base&varBase(int var) {_varBase = var; return *this;}
> private:
> int _varBase;
> };
> class Derived: public Base {
> public:
> Derived(): _varDerived(0) {}
> Derived&varDerived(int var) {_varDerived = var; return *this;}
> // ugly forwarding function
> Derived&varBase(int var) {varBase(var); return *this;}
> private:
> int _varDerived;
> };
> int main() {
> Derived w = Derived().varDerived(42);
> // the forwarding function is needed for all of these.
> Derived x = Derived().varBase(4711);
> Derived y = Derived().varDerived(42).varBase(4711);
> Derived z = Derived().varBase(4711).varDerived(42);
> }
>
> It works fine so far, but now imagine that the classes have more
> member variables and that the inheritance hierarchy is deeper than 2
> (i.e. we have classes DerivedFromDerived, ...). Then, _each_ of the
> derived classes would need a forwarding function for _every_ variable
> in _any_ of its base classes, which doesn't scale very well.
>
> Is anyone aware of a way to avoid these forwarding function(s)?


I am sorry, it is unclear from what you presented here, what it is that
you're trying to accomplish. Why would you want to expose member
variables like that? Seems to violate any sensible encapsulation and
implementation hiding principle.

V
--
I do not respond to top-posted replies, please don't ask
 
Reply With Quote
 
 
 
 
Christof Warlich
Guest
Posts: n/a
 
      06-14-2012
> > // ugly forwarding function
> > Derived&varBase(int var) {varBase(var); return *this;}


> I am sorry, it is unclear from what you presented here, what it is that
> you're trying to accomplish. *Why would you want to expose member
> variables like that? *Seems to violate any sensible encapsulation and
> implementation hiding principle.


The example just implements (part of) the "named parameter" idiom as
described in http://www.parashift.com/c++-faq-lit...html#faq-10.20
and extends it in the presence of inheritance. I've deliberately left
out the additional effort of proper encapsulation to concentrate on
the issue:

What I'd like to accomplish is to find a way to get rid of the "ugly
forwarding function"(s) as commented in the code, as they are required
for _every_ variable in _every_ derived class.

Anyhow, I fear that I may be out of luck, there is most probably no
such way .

Cheers,

Chris


 
Reply With Quote
 
Victor Bazarov
Guest
Posts: n/a
 
      06-14-2012
On 6/14/2012 10:34 AM, Christof Warlich wrote:
>>> // ugly forwarding function
>>> Derived&varBase(int var) {varBase(var); return *this;}

>
>> I am sorry, it is unclear from what you presented here, what it is that
>> you're trying to accomplish. Why would you want to expose member
>> variables like that? Seems to violate any sensible encapsulation and
>> implementation hiding principle.

>
> The example just implements (part of) the "named parameter" idiom as
> described in http://www.parashift.com/c++-faq-lit...html#faq-10.20
> and extends it in the presence of inheritance. I've deliberately left
> out the additional effort of proper encapsulation to concentrate on
> the issue:
>
> What I'd like to accomplish is to find a way to get rid of the "ugly
> forwarding function"(s) as commented in the code, as they are required
> for _every_ variable in _every_ derived class.


They are required to exist in the corresponding class for _every_
variable, yes. As many "ugly forwarding functions" as there are those
"parameters" that you'd like to use "named", regardless of inheritance.
Do you find that not to be true?

> Anyhow, I fear that I may be out of luck, there is most probably no
> such way .


Well, yeah, sort of. I speculate that you don't really want to use
inheritance here. The article in the FAQ talks about a supplemental
class for constructing an instance of another class, right? Why would
there be a need to inherit that supplemental class? Perhaps it's the
sole point of the exercise, but then it's an exercise in futility,
really. You don't like the "forwarding functions", whereas those are
pretty much the only reasonable way to implement the "named parameters"
(at least as far as the FAQ is suggesting). It's like asking, 'Can I
avoid the hardware interrupt when I perform an operation that causes a
hardware interrupt?' The answer is "no", and there is no sense in
looking any further.

Of course, it's possible that I didn't understand you, in which case,
I'm open to starting over, perhaps you could restate your problem (using
a simpler case, but let's be close to modeling real world here).

V
--
I do not respond to top-posted replies, please don't ask
 
Reply With Quote
 
Alf P. Steinbach
Guest
Posts: n/a
 
      06-14-2012
On 14.06.2012 09:41, Christof Warlich wrote:
> Hi,
>
> please consider the following code, using named parameters for object
> instantiation:
>
> class Base {
> public:
> Base(): _varBase(0) {}
> Base&varBase(int var) {_varBase = var; return *this;}
> private:
> int _varBase;
> };
> class Derived: public Base {
> public:
> Derived(): _varDerived(0) {}
> Derived&varDerived(int var) {_varDerived = var; return *this;}
> // ugly forwarding function
> Derived&varBase(int var) {varBase(var); return *this;}
> private:
> int _varDerived;
> };
> int main() {
> Derived w = Derived().varDerived(42);
> // the forwarding function is needed for all of these.
> Derived x = Derived().varBase(4711);
> Derived y = Derived().varDerived(42).varBase(4711);
> Derived z = Derived().varBase(4711).varDerived(42);
> }
>
> It works fine so far, but now imagine that the classes have more
> member variables and that the inheritance hierarchy is deeper than 2
> (i.e. we have classes DerivedFromDerived, ...). Then, _each_ of the
> derived classes would need a forwarding function for _every_ variable
> in _any_ of its base classes, which doesn't scale very well.
>
> Is anyone aware of a way to avoid these forwarding function(s)?


http://alfps.wordpress.com/2010/05/1...uments-in-c98/

Cheers & hth.,

- Alf


 
Reply With Quote
 
Luca Risolia
Guest
Posts: n/a
 
      06-14-2012
On 14/06/2012 09:41, Christof Warlich wrote:
> It works fine so far, but now imagine that the classes have more
> member variables and that the inheritance hierarchy is deeper than 2
> (i.e. we have classes DerivedFromDerived, ...). Then, _each_ of the
> derived classes would need a forwarding function for _every_ variable
> in _any_ of its base classes, which doesn't scale very well.
>
> Is anyone aware of a way to avoid these forwarding function(s)?


If you just want to instantiate the most derived class, use this idiom:

template<class D>
class Base {
public:
Base() : _varBase(0) { }
D& varBase(int var) {
_varBase = var;
return *static_cast<D*> (this);
}
private:
int _varBase;
};

class Derived : public Base<Derived> {
public:
Derived() : _varDerived(0) { }
Derived& varDerived(int var) {
_varDerived = var;
return *this;
}
private:
int _varDerived;
};

 
Reply With Quote
 
AdlerSam
Guest
Posts: n/a
 
      06-16-2012
> http://alfps.wordpress.com/2010/05/1...ped-optional-a...

Interesting, thanks for the insight.
 
Reply With Quote
 
AdlerSam
Guest
Posts: n/a
 
      06-16-2012
> If you just want to instantiate the most derived class, use this idiom:
>
> template<class D>
> class Base {
> public:
> * * *Base() : _varBase(0) { }
> * * *D& varBase(int var) {
> * * * * *_varBase = var;
> * * * * *return *static_cast<D*> (this);
> * * *}
> private:
> * * *int _varBase;
>
> };
>
> class Derived : public Base<Derived> {
> public:
> * * *Derived() : _varDerived(0) { }
> * * *Derived& varDerived(int var) {
> * * * * *_varDerived = var;
> * * * * *return *this;
> * * *}
> private:
> * * *int _varDerived;
>
>
>
>
>
>
>
> };

Yes, that should pretty much fit my needs. Thanks a lot!

 
Reply With Quote
 
Alain Ketterlin
Guest
Posts: n/a
 
      06-17-2012
AdlerSam <(E-Mail Removed)> writes:

>> template<class D>
>> class Base {
>> public:
>> * * *Base() : _varBase(0) { }
>> * * *D& varBase(int var) {
>> * * * * *_varBase = var;
>> * * * * *return *static_cast<D*> (this);
>> * * *}
>> private:
>> * * *int _varBase;
>>
>> };
>>
>> class Derived : public Base<Derived> {
>> public:
>> * * *Derived() : _varDerived(0) { }
>> * * *Derived& varDerived(int var) {
>> * * * * *_varDerived = var;
>> * * * * *return *this;
>> * * *}
>> private:
>> * * *int _varDerived;


> Yes, that should pretty much fit my needs. Thanks a lot!


Note that you have lost your base class, since Base<Derived1> and
Base<Derived2> are completely unrelated. You're basically using
templates and inheritance to factor out common text.

-- Alain.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Function named and called by a parameter value? Tuxedo Javascript 2 02-14-2012 10:02 PM
Inheritance in Pimpl idiom George2 C++ 0 03-18-2008 05:33 AM
named parameters idiom Fernando Cacciola Ruby 5 11-06-2007 05:33 PM
Named arguments and inheritance Pacific Fox Javascript 34 11-17-2006 09:34 AM
Named Constructor idiom - a question Steve C++ 10 07-23-2005 12:42 PM



Advertisments