Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When defining a member function out-of-line, which qualifiers must appear in the declaration / definition / both?

Tags:

c++

qualifiers

I am almost sure this has been asked before. Unfortunately, my C++ has become so rusty that I don't even know what to search for.

Is there an easy-to-remember rule of thumb that would tell me which qualifiers (inline, virtual, override, const, mutable, etc.) must appear (a) only in the declaration, (b) only in the definition, (c) both in the declaration and definition when I define a member function out-of-line?

Example:

struct Geometry {
    …
    virtual Geometry* clone() const = 0;
};

struct Point2 : public Geometry {
    …
    virtual Point2* clone() const override { … }
};

If I wanted to define Point2::clone out-of-line, trial and error leads me to believe that this would be the correct code:

struct Point2 : public Geometry {
    …
    virtual Point2* clone() const override;
};

Point2* Point2::clone() const { … }
  • The virtual and override qualifiers may appear only in the declaration.
  • const must appear in both the declaration and definition.

I would not want to rely on trial and error forever. But I want to be explicit about qualifiers (i.e. repeat them even if e.g. they are implied by a base class.) Is there a general rule which qualifier has to go exactly where, or are the rules different for each of them?

like image 866
stakx - no longer contributing Avatar asked Nov 15 '25 00:11

stakx - no longer contributing


2 Answers

General rule is that when removing a qualifier produces a different function overload, that qualifier must appear in both places. All other qualifiers stay in the declaration.

The three qualifiers that must appear in both places are const and the two kinds of reference qualifiers, which appear in the C++11 standard:

void foo() const;
void foo() &;
void foo() &&;

All other qualifiers stay in the declaration.

like image 120
Sergey Kalinichenko Avatar answered Nov 17 '25 20:11

Sergey Kalinichenko


The best way to know which modifiers (or "specifiers") have to be used in which instance is to understand what each one of them means, and what they do.

const is a part of the method's "signature". A signature consists of what the function returns, the types of its parameters, and whether it is a constant method (the const part). That cannot be changed, and must remain as is.

Everything else, virtual, and override in your list, is related to the method's declaration. It's not a part of the method's signature, and can only appear in the method's declaration.

The only rule of thumb, if there is one, is that anything that's a part of the method's signature must be unchanged, when the method is not defined inline. And if it's not, it must be a part of the declaration, only (but, as with every rule of thumb, there's always an exception, the inline keyword).

Note that default parameter values are not considered to be a part of the method's signature. Default parameter values must be specified in the declaration only. But, if the method is defined inline, the default parameter values wind up as part of the method's definition!

like image 29
Sam Varshavchik Avatar answered Nov 17 '25 18:11

Sam Varshavchik



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!