У меня есть класс с названием book, в котором есть книги.

#ifndef BOOK_H
#include<string>
#include<vector>
#include<iostream>
#define BOOK_H
class book
{
public:
    std::string Author, Title;
    int Year;
    book(){}
    book(std::string author, std::string title, int year);
    ~book(){}
    void add_book();
    std::vector<book*>library;
};  
#endif

Book.cpp файл

#include "book.h"

book::book(std::string author, std::string title, int year)
:Author(author), Title(title), Year(year){} 

void book::add_book()
{
    int y;
    std::string a, t;
    std::cin>>a;
    std::cin>>t;
    std::cin>>y;
    library.push_back(new book(a, t, y));
}

Но когда я хочу добавить новый book в библиотеку, я получаю ошибку сегментации во время push_back нового объекта в файле main.cpp

#include "book.h"

int main()
{
    book* ptr;
    ptr->add_book();
    return 0;
}

Может ли кто-нибудь объяснить мне, в чем проблема?

Я новичок в ООП, и хотя я прочитал здесь много сообщений, я все еще не могу найти решение.

c++
1
Michał Habigier 25 Апр 2016 в 12:28

3 ответа

Лучший ответ

Вы не инициализируете ptr в main;

int main()
{
    book* ptr = new book(); // initialize it here
    ptr->add_book();
    return 0;
}

Это исправит segfault, однако я не уверен в логике, связанной с образцом кода, и возможных утечках памяти.


Я бы хотел отделить library от типа book для лучшей композиции и избежать выделения кучи;

#include<string>
#include<vector>
#include<iostream>

class book
{
public:
    std::string Author, Title;
    int Year;
    book(){}
    book(std::string author, std::string title, int year) : Author(author), Title(title), Year(year) {} 
    ~book(){}
};  

struct library {
    std::vector<book> books_;
    void add_book(const book& value) { books_.push_back(value); }
};

int main()
{
    library lib;
    int y;
    std::string a, t;
    std::cin>>a;
    std::cin>>t;
    std::cin>>y;
    lib.add_book(book(a, t, y));
    return 0;
}
2
Niall 25 Апр 2016 в 09:46

Ну вот:

book* ptr;
ptr->add_book();

ptr не назначен, поэтому его использование вызывает ошибку сегмента. Перед применением его следует назначить:

Ptr = новая книга ();

Это вызовет утечку памяти, поэтому я предлагаю (если вам нравится динамическое распределение):

auto ptr = std::make_unique<book>();
ptr->add_book();

Но зачем вам все равно нужен указатель, вот это:

book bk;
bk.add_book();

Будет работать так же.


С другой стороны, почему ваш класс book хранит вектор экземпляров book? Вам нужен класс library, который будет хранить вектор книг.

1
marcinj 25 Апр 2016 в 09:42

Вам нужно будет создать объект класса Book перед использованием его методов.

Book *ptr = new Book();
1
Priyansh Goel 25 Апр 2016 в 09:37