На конструктор по умолчанию нельзя ссылаться

Я делаю школьный проект, и мне нужно создать библиотечную систему с двунаправленным списком и структурами. Я хочу реализовать конструкторы, чтобы сделать мой код более понятным. Проблема возникает, когда я хочу создать структуру для двунаправленного списка и зарезервировать место в памяти для элемента списка, используя new list_of_books. Сообщение об ошибке, которое я получаю, не соответствует вызову функции Book::Book(), а на конструктор по умолчанию "list_of_books" нельзя ссылаться - это удаленная функция. Что это значит и как я могу это исправить?

struct User {
  std::string name;
  std::string surname;
  User(std::string name, std::string surname) 
    : name(name), surname(surname) {}
};

struct Date {
  int day;
  int month;
  int year;
  Date(int day, int month, int year) 
    : day(day), month(month), year(year) {}
};

struct Book {
  int id;
  std::string title;
  struct User author;
  std::string cathegory;
  struct Date hire_date;
  struct User reader;
  std::string others;
  Book(int id, std::string title, std::string nameA, std::string surnameA, std::string cathegory, int day, int month, int year, std::string nameR, std::string surnameR, std::string others) 
    : id(id), title(title), author(nameA, surnameA), cathegory(cathegory), hire_date(day, month, year), reader(nameR, surnameR), others(others) {}
};

struct list_of_books {
  struct Book book;
  list_of_books* next;
  list_of_books* prev;
};

void push(Book data) {
  if (head == NULL) {
    list_of_books* element = new list_of_books;
    element->book = data;
    element->prev = NULL;
    element->next = NULL;
    head = element;
  } else {
    list_of_books* curr = head;

    while(curr->next != NULL) {
      curr = curr->next;
    }

    list_of_books* element = new list_of_books;
    element->book = data;
    element->prev = curr;
    element->next = NULL;
    curr->next = element;
  }
}

TL;DR: вы получаете конструктор по умолчанию бесплатно только в том случае, если вы не определяете конструктор самостоятельно. Отвечает ли это на ваш вопрос? Есть ли в C++ неявный конструктор по умолчанию?

scohe001 23.12.2020 15:07

Я так не думаю, решение, которого я хочу достичь, состоит в том, чтобы иметь конструктор в структуре Book, но не использовать его в структуре list_of_books. Я думаю, что ошибка возникает из-за того, что структура списка наследует конструктор от структуры книги, но я его не использую. Поэтому мне нужно каким-то образом использовать структуру Book в структуре list_of_books без использования конструктора книг.

BooBoo 23.12.2020 15:12

вы используете его в struct list_of_books, у него есть член struct Book book;, и вы пытаетесь создать его через list_of_books* element = new list_of_books;. Как вы хотите создать участника book при создании list_of_books?

463035818_is_not_a_number 23.12.2020 15:15
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
3
1 806
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий
struct User {
  std::string name;
  std::string surname;
  User(std::string name, std::string surname) 
    : name(name), surname(surname) {}
};

этот конструктор вреден. У вас есть агрегат — тип, который является его данными — и конструктор, который просто повторяет элементы по порядку.

Сделай это:

struct User {
  std::string name;
  std::string surname;
};

и повторите для каждого другого конструктора, который вы написали.

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

Если вы удалите все конструкторы в своей программе, ваша программа скомпилируется.


Теперь что происходит не так? Создавая конструктор, вы удаляете конструктор по умолчанию без аргументов.

Затем, когда вы new list_of_books, он пытается использовать конструктор для Book, которого не существует.


Обратите внимание, что при работе с агрегатами вы должны использовать списки построения скобок {}, если вы хотите построить их на месте, например Book b = {"The Bookiest Book", "Bob Smith"};, вместо () для аргументов.

О, хорошо, я не знал, что не должен создавать конструкторы такого типа, и я даже не знал о таком типе объявления Book b = {...}. Это очень помогает. Я создал конструкторы, потому что мне нужно прочитать данные из .txt файла, и я не могу использовать getline(), потому что я сохраняю их в разные типы структурных переменных, и я подумал, что конструкторы мне помогут. Большое спасибо за ответ.

BooBoo 23.12.2020 15:46

@booboo также делают int day=0; и т. д.; эти ctors могут быть полезны, но если вы добавите их, ctor по умолчанию будет удален.

Yakk - Adam Nevraumont 23.12.2020 16:48

Другие вопросы по теме