简体   繁体   中英

Defaulted default constructor triggers -Werror=effc

Teaching myself C++ and working on an example from a book I picked up at the local Barnes and Noble. "Professional C++ by Marc Greggoire". I didn't realize that this book was meant for someone with a little more experience than myself but I've been muddling through it with the help of online tutorials and of course SO.

The example is an Employee class that has two constructors. One explicitly defaulted and the other intitializing private members with references.

Using Code Blocks IDE this code:

#include <iostream>
#include <string>
using namespace std;

class Employee
{
public:

    Employee() = default;                           //default constructor
    Employee(const std::string& firstName,
             const std:: string& lastName);

private:
    std::string mFirstName;
    std::string mLastName;
};

Employee::Employee(const string& firstName, const string& lastName) : mFirstName(firstName), mLastName(lastName)
{
}

int main()
{
    cout << "Testing the Employee class." << endl;

    Employee emp;

    return 0;
}

generates a compiler warning on the explicitly defaulted constructor that the variables should be initialized in a member initialization list [-Werror=effc] .

Quick search of SO shows that maybe this can be ignored.

Can I ignore the gcc warning: 'Foo::m_bar' should be initialized in the member initialization list [-Weffc++]

Since I'm not quite understanding why this is ok to ignore, I tried anyway to get the warning to go away by providing a member initialization in a definition for the default constructor:

Employee::Employee() : mFirstName("Empty"), mLastName("Empty")
{
}

only to find that an error has now been generated by the compiler about the explicitly defaulted constructor, "error: definition of explicitly-defaulted 'Employee::Employee()' and the previous warning remaining. Another SO search gave me this:

How is "=default" different from "{}" for default constructor and destructor?

It seems to indicate that using Employee() = default; would be more clear but using Employee(); will still work. So I kept the default constructor initialization and changed the default constructor declaration from:

Employee() = default;

to

Employee();

Now the compiler is happy with the new default constructor declaration with member initialization list but I'd really like to understand what is going on here. I understand completely why (from the SO discussions) the compiler errors if there is an explicitly defaulted constructor yet a user provides an initialization list. This makes sense. What doesn't make sense to me is why the compiler is asking for one when clearly, providing one with an explicitly defaulted constructed is contradictory.

As the linked post says, that warning is a bug in your compiler.

The code was fine, and the initialisation was fine. The default ed default constructor (.) will default-construct the string members too.

Your attempt to workaround the warning in another way involved creating your own default constructor, even though you've declared it as default ed. That's like getting in and driving an automatic car, then opening the bonnet en route and trying to change gear yourself.

Removing default then makes it just a normal, user-declared default constructor and everything's fine again… if more verbose than it needed to be.

(The re-use of the word "default" is a really unfortunate choice by the committee!)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM