On Apr 14, 11:51 am, Vidar Hasfjord <vattilah-gro...@[EMAIL PROTECTED]
>
wrote:
> In C++ you are allowed to declare an incomplete type (a "forward").
> Code can operate on references and pointers to such types. This is a
> very nice feature with regard to encapsulation.
>
> I often use this feature to omit detail in interfaces; detail that not
> all clients need to know. For example:
>
> class Component {
> //...
> public:
> class Parameter;
> virtual Parameter* get_parameter ();
> };
>
> Client code can use Component and even pass pointers to Parameters
> around while still being blissfully unaware of Parameter's definition.
> Clients that need to know can include a separate header where
> Parameter is defined.
>
> This works nicely except when the Parameter class really is private
> and clients only should see an abstract interface, i.e.:
>
> class Component {
> public:
> class IParameter {
> public:
> virtual string get_name () = 0;
> virtual string get_value () = 0;
> };
> virtual IParameter* get_parameter ();
> };
There is no reason to declare IParameter's virtual methods as pure -
because the library does in fact provide implementations of those
routines. Pure virtual methods necessitate that the client provide
implementations - but there is no such requirement in this case.
Instead, the Library interface should declare IParameter along these
lines:
class Component
{
public:
...
class IParameter
{
public:
virtual string get_name();
virtual string get_value();
};
virtual IParameter* get_parameter ();
};
The Library then internally defines Component and IParameter
subcl*****:
// Internal Library Class Declarations
class ComponentImpl : public Component
{
class Parameter : public IParameter
{
public:
Parameter() : IParameter() {}
virtual ~Parameter() {}
// ...
};
virtual Parameter * get_parameter()
{
return new Parameter;
}
};
Essentially, the Library's factory method returns pointers to concrete
subtypes of the Library's publicly-declared interface cl*****. In this
way, the Library takes advantage of C++'s dynamic types and virtual
method dispatch to furnish implementations without exposing irrelevant
details.
> It would be nice if it was possible to *partially* complete a type.
> This would mean to specify the base (or bases) of a type without
> providing the full definition.
> ... The client code knows
> only that Parameter inherits IParameter and is hence restricted to use
> that interface, while the implementation code that has seen the full
> Parameter definition can use all its methods and members; without need
> for downcasting.
The solution is for the Library to make only the "Parameter" class
public - and to declare its "IParameter" subclass internally.
> Any views on the feasability of such a feature?
The C++ language already sup****ts this behavior with virtual functions
and dynamic types.
Greg
--
[ See http://www.gotw.ca/resources/clcm.htm
for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


|