Const& , & and && Specifiers For Member Functions in C++

const& , & and && specifiers for member functions in C++

const& means, that this overload will be used only for const, non-const and lvalue object.

const A a = A();
*a;

& means, that this overload will be used only for non-const object.

A a;
*a;

&& means, that this overload will be used only for rvalue object.

*A();

for more information about this feature of C++11 standard you can read this post What is "rvalue reference for *this"?

what is the && means at the end of a function

&& at the end of the function mean that the function is chosen when this has r-value value category.

See member functions:

A non-static member function can be declared with no ref-qualifier, with an lvalue ref-qualifier (the token & after the parameter list) or the rvalue ref-qualifier (the token && after the parameter list). During overload resolution, non-static cv-qualified member function of class X is treated as follows:

no ref-qualifier: the implicit object parameter has type lvalue reference to cv-qualified X and is additionally allowed to bind rvalue implied object argument

lvalue ref-qualifier: the implicit object parameter has type lvalue reference to cv-qualified X

rvalue ref-qualifier: the implicit object parameter has type rvalue reference to cv-qualified X

Should member functions be const if they affect logical state, but not bitwise state?

I believe that const should reflect logical const-ness, regardless of the internal representation. Just because your object contains only a pointer to something that changes, doesn't mean all your member functions should be const.

C++ even has the mutable concept for internal representation that needs to change even if conceptually the object does not. The const keyword is clearly not intended to represent "bitwise" const-ness.

How member functions' additional syntax/specifiers affect memory layout in classes?

Member functions are not part of an object's memory layout. The only thing attributable to member functions is a hidden reference to an implementation-defined structure used to perform dynamic dispatch, such as a virtual method table. This reference is added to your object only if it has at least one virtual member function, so objects of classes that do not have virtual functions are free from this overhead.

Going back to your specific question, the only modifier to a member function that has any effect on the object's memory layout is virtual*. Other modifiers have an effect of how the function itself is interpreted, but they do not change the memory layout of your object.

* override keyword also indicates the presence of a virtual member function in a base class, but it is optional; adding or removing it does not change memory layout of the object.

Universal member-function definition, instanceable from both 'const' & 'non-const' objects

To build upon the answer by @dyp in the comments:

You do indeed need two separate functions if you want to overload on the constness of this. However, you can minimize duplication by offloading the work to a helper function.

@dyp suggested using a friend function template for this, but friend functions have no access control, so I would normally prefer a static member function instead; you can then make it private or protected:

template <typename T>
struct sList
{
void DoForEachList(auto pFunc)
{
DoForEachListHelper(*this, pFunc);
}
void DoForEachList(auto pFunc) const
{
DoForEachListHelper(*this, pFunc);
}
private:
static void DoForEachListHelper(auto&& self, auto pFunc)
{
for(auto p = &self; p; p = pNext->pNext)
pFunc(p);
}
};

Can overloading is possible with two version of function, constant member function and function without const

Yes you can.

If you have

MyClass m;
m.doSomething();

The non-const version will be called. When you have

const MyClass m;
m.doSomething();

The const version will be called.

Question about overloaded member functions in C++?

In C++, you can declare a member function of a class to be const, by appending that keyword to its signature (for instance, int MyClass:doSomething(int param) const {...}). Doing so guarantees that the function won't change the (non-mutable) members of the class object on which the function is called - and hence it can be called with const instances of that class.

It is permissible to have two different member functions for a class whose signature differs only in whether they are declared const or not.

C++: const reference, before vs after type-specifier

No difference as const is read right-to-left with respect to the &, so both represent a reference to an immutable Fred instance.

Fred& const would mean the reference itself is immutable, which is redundant; when dealing with const pointers both Fred const* and Fred* const are valid but different.

It's a matter of style, but I prefer using const as a suffix since it can be applied consistently including const member functions.



Related Topics



Leave a reply



Submit