Note: "person:: person()" неявно удаляется, поскольку определение по умолчанию будет плохо сформировано

Я работаю над примером программы, чтобы помочь мне изучить структуры на С++. Здесь мой код:

#include <stdio.h>
#include <iostream>
#include <string>

using namespace std;

int nextPersonID = 0;
int nextAddressID = 0;

struct date {
    int day;
    int month;
    int year;
};

struct address {
    int id;
    string address;
    date effectiveDate;
    date expirationDate;
};

struct person {
    int id;
    string name;
    date birthdate;
    const int numberOfAddresses;
    address addresses [1];
};

int main () {
    person bob;
    bob.name = "Bob";
    bob.id = nextPersonID;
    nextPersonID++;
    bob.birthdate.day = 1;
    bob.birthdate.month = 1;
    bob.birthdate.year = 1990;
    bob.numberOfAddresses = 1;
    bob.addresses[0].address = "31415 E. Pi Blvd.";
    bob.addresses[0].id = nextAddressID;
    nextAddressID++;
    bob.addresses[0].effectiveDate.day = 1;
    bob.addresses[0].effectiveDate.month = 1;
    bob.addresses[0].effectiveDate.year = 1990;
    bob.addresses[0].expirationDate.day = 1;
    bob.addresses[0].expirationDate.day = 1;
    bob.addresses[0].expirationDate.day = 2020;
    cout << bob.name;
}

Но когда я пытаюсь скомпилировать, он терпит неудачу с note: 'person::person()' is implicitly deleted because the default definition would be ill-formed.. Здесь мой журнал построения:

-------------- Build: Debug in DataStructures (compiler: GNU GCC Compiler)---------------

mingw32-g++.exe -Wall -g -std=c++11 -I"C:\Program Files (x86)\CodeBlocks\MinGW_Dev_Libs\include\SDL2" -c C:\Users\Duncan\Documents\C++\Challenges\DataStructures\DataStructures.cpp -o obj\Debug\DataStructures.o
C:\Users\Duncan\Documents\C++\Challenges\DataStructures\DataStructures.cpp: In function 'int main()':
C:\Users\Duncan\Documents\C++\Challenges\DataStructures\DataStructures.cpp:32:12: error: use of deleted function 'person::person()'
C:\Users\Duncan\Documents\C++\Challenges\DataStructures\DataStructures.cpp:23:8: note: 'person::person()' is implicitly deleted because the default definition would be ill-formed:
C:\Users\Duncan\Documents\C++\Challenges\DataStructures\DataStructures.cpp:23:8: error: uninitialized non-static const member 'const int person::numberOfAddresses'
C:\Users\Duncan\Documents\C++\Challenges\DataStructures\DataStructures.cpp:39:29: error: assignment of read-only member 'person::numberOfAddresses'
Process terminated with status 1 (0 minute(s), 1 second(s))
3 error(s), 0 warning(s) (0 minute(s), 1 second(s))

Я не могу найти что-либо с Google в отношении моей проблемы. Есть идеи? Я использую Code:: Blocks с g++.

Ответ 1

Ну, проблема не в том, что "примечание". "Примечание" просто объясняет причину ошибки. Ошибка заключается в том, что вы пытаетесь построить по умолчанию свой объект person, если класс person не имеет конструктора по умолчанию.

Вместо того, чтобы пытаться построить его по умолчанию, вы можете {} - инициализировать этот константный член и код будет компилировать

person bob = { nextPersonID++, "Bob", {}, 1 };
bob.birthdate.day = 1;
bob.birthdate.month = 1;
bob.birthdate.year = 1990;
...

Кроме того, вы можете просто написать свой собственный конструктор по умолчанию для класса.

Ответ 2

Проблема не связана с "конструкцией по умолчанию... когда у класса нет конструктора по умолчанию". Проблема связана с наличием константы в объявлении класса и конструктора, который не гарантирует, что константа будет определена. Предложите использовать "список инициализаторов".

struct Person {
        int id;
        string name;
        date birthdate;
        const int numberOfAddresses;
        address addresses [1];

        Person(int); // constructor declaration
        Person() : numberOfAddresses(1) {} // constructor definition.
                      // ": numberOfAddresses(1)" is the initializer list
                      // ": numberOfAddresses(1) {}" is the function body
    };
    Person::Person(int x) : numberOfAddresses(x) {} // constructor definition. ": numberOfAddresses{x}" is the initializer list
    int main()
    {
        Person Bob; // calls Person::Person()
        Person Shurunkle(10); // calls Person::Person(int)
    }