Method overloading with const/non-const variants (was: Re: KDE/kdelibs/kdecore)
Richard Dale
rdale at foton.es
Tue Jul 8 14:20:08 BST 2008
On Tuesday 08 July 2008 13:55:23 Thiago Macieira wrote:
> Friedrich W. H. Kossebau wrote:
> >What about overloaded methods? Hm, running the test from below shows me
> > that I have been thinking wrong for many years, duh. So the compiler
> > chooses the variant by the constness of the object? I thought it takes
> > all possible variants and then narrows the selection further by the
> > LHS, going for constness if possible?
> >
> >Is this defined by the C++ specs? Does anyone know the rationale behind
> > this?
>
> Yes, this is defined by the C++ spec. When you call a function foo(...)
> with a set of parameters, the compiler will try to find all instances
> of "foo" in the class and see which one fits best to the parameters you
> gave.
>
> I don't know the exact rules for type promotion and demotion, but there
> are cases where it becomes ambiguous. If it does, then the compiler will
> print an error and ask you what to do.
>
> An interesting thing about the search is when it happens to template
> types: no promotion or demotion is applied. The compiler searches only
> for the exact match.
>
> The compiler always selects the less constraining overload of a function
> given its CV-qualifiers (CV = const, volatile). If you have the following
> four overloads of foo():
>
> void foo();
> void foo() const;
> void foo() volatile;
> void foo() const volatile;
>
> The CV qualifier to a function applies to the this pointer implicit
> parameter. So you can think of that as:
>
> void foo(Class *this);
> void foo(const Class *this);
> void foo(volatile Class *this);
> void foo(const volatile Class *this);
>
> So now you can apply the same rules as parameter overloading. That's why
> the compiler chooses the less constraining one. That's also why
> the "const" variants may be called in any circumstances, but the
> non-const ones cannot be called with a const object.
I think it is great that people can understand these rules, and manage to
write code where they understand how it works. But personally I wish we
didn't use const overloading in KDE libs unless absolutely necessary. There
are no other languages apart from C++, that use const overloading as far as I
know, and it makes it awkward for language bindings.
Here are the const/non-const method overloads in the kde headers, with the
comments extracted. Most of them do the same thing according to the comments.
Only two or three actually have different behaviour. I would prefer that we
deprecate one of the const or non-const methods that are the same at least.
-- Richard
/**
* Returns an object for the named subgroup.
*
* @param group the group to open. Pass a null string on to the KConfig
* object to obtain a handle on the root group.
* @return The list of groups.
**/
KConfigGroup group(const QByteArray &group);
KConfigGroup group(const QString &group);
KConfigGroup group(const char *group);
/**
* @overload
**/
const KConfigGroup group(const QByteArray &group) const;
const KConfigGroup group(const QString &group) const;
const KConfigGroup group(const char *group) const;
/**
* Return the config object that this group belongs to.
*/
KConfig* config();
const KConfig* config() const;
/**
* Return the @ref KConfig object used for reading and writing the settings.
*/
KConfig *config();
/**
* Return the @ref KConfig object used for reading and writing the settings.
*/
const KConfig *config() const;
/**
* Sets the desktop action group.
* @param group the new action group
*/
KConfigGroup actionGroup(const QString &group);
const KConfigGroup actionGroup(const QString &group) const;
/**
* Returns the context menu associated with this menu
* The data property of all actions inserted into the context menu is
modified
* all the time to point to the action and menu it has been shown for
*/
QMenu* contextMenu();
/**
* Returns the context menu associated with this menu
*/
const QMenu* contextMenu() const;
/**
* Returns the page widget of the dialog or 0 if no page widget is set.
*/
KPageWidget *pageWidget();
/**
* Returns the page widget of the dialog or 0 if no page widget is set.
*/
const KPageWidget *pageWidget() const;
/**
* @return the axis of the specified @p type, or 0 if no axis has been
set.
* @sa Axis
*/
KPlotAxis* axis( Axis type );
/**
* @return the axis of the specified @p type, or 0 if no axis has been
set.
* @sa Axis
*/
const KPlotAxis* axis( Axis type ) const;
/**
* Returns the QProgressBar used in this dialog.
* To set the number of steps or other progress bar related
* settings, access the QProgressBar object directly via this method.
*/
QProgressBar *progressBar();
/**
* Returns the QProgressBar used in this dialog.
* To set the number of steps or other progress bar related
* settings, access the QProgressBar object directly via this method.
*/
const QProgressBar *progressBar() const;
More information about the kde-core-devel
mailing list