tdf#74702 2/2

Michael Stahl mst at
Mon Jul 8 10:01:53 UTC 2019

On 06.07.19 19:59, Adrien Ollier wrote:
> So to close bug #74702, we require to keep the real type of any 
> OutputDevice* a function gets as argument.
> If we are in a function g(OutputDevice*), we must rewind to its caller 
> f(OutputDevice*), and so on until a(OutputDevice*) which is called after 
> creation of an instance of a subclass of OutputDevice.
> As you understand, it is very hard because there are many and many 
> functions to modify and to rewind to get the real type of the 
> OutputDevice* (OutputDevice subclass) that was passed as parameter.
> An alternative is to use dynamic_cast and test the result. This solution 
> does not require so much changes but is less elegant and efficient.
> Community, which solution do you prefer?

oh no, i stopped reading your other mail too early, you don't agree...

well there are some options:

1) keep tag enums
    + conditions are fast
    - violates the purity of object-oriented dogma
2) use dynamic_cast instead
    - slow
    +- it is semi-object-oriented (at first glance you're making use
       of subtyping but in reality it's not)
3) virtual operator subclass*() + overrides + conditionals
    - if you think the other options are ugly, you haven't seen this one
      in action
4) add more virtuals to OutputDevice, call them from g()
    + object oriented
    - the logic may not "belong" to OutputDevice
    - every time one of those virtuals changes you'll have to rebuild
      ~4000 objects and wait an hour
5) visitor pattern
    + very object oriented, straight from design patterns book
    - lots of additional complexity, logic is distributed around multiple
      functions (that's another way of writing "very object oriented"?)
6) multi-methods
    + rather simple & elegant
    - haha, we dont use CLOS

> I could try the first solution but to do so I need you to understand 
> that keeping the real type of an object is crucial, essential. And to 
> get this achevied, I need your cooperation for modifying functions that 
> do not return the real type of an newly created object into a function 
> that returns the real type of the object.
> Example is OutputDevice*Application::GetDefaultDevice()which calls 
> ImplGetDefaultWindow()which returns a vcl::Window*.
> Application::GetDefaultDeviceā€‹ should return a vcl::Window*so that 
> functions that act differently for Windows can be used instead of 
> functions that take any OutputDevicebut that are in trouble when they 
> require to do something special with Windows.

in this particular case it might be possible to change it, but i bet 
you'll find other functions that may return several different subclasses 
of OutputDevice, and overloading in C++ has the limitation that you 
can't overload the return type, so you'd be out of luck then.

More information about the LibreOffice mailing list