named parameter idiom and inheritance

C

Christof Warlich

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
 
V

Victor Bazarov

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
 
C

Christof Warlich

// ugly forwarding function
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-lite/ctors.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
 
V

Victor Bazarov

The example just implements (part of) the "named parameter" idiom as
described in http://www.parashift.com/c++-faq-lite/ctors.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
 
A

Alf P. Steinbach

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/19/cppx-how-to-do-typed-optional-arguments-in-c98/

Cheers & hth.,

- Alf
 
L

Luca Risolia

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

AdlerSam

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!
 
A

Alain Ketterlin

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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,039
Messages
2,570,375
Members
47,020
Latest member
anuradha

Latest Threads

Top