Camila Braz
Camila Braz

Reputation: 1

Exceptions inside methods c++

I'm trying to catch an exception inside a method and my code isnt working because the exception shuts the program down before calling the destructors

main.cpp:

#include "register.h"
#include "agenda.h"
#include "professionalregister.h"
#include "personalregister.h"
#include <iostream>
#include <stdexcept>

int main(){
    Agenda agenda (2);
    Register *profissional_1 = new ProfessionalRegister ("camila", 1, 2, "engenheira", "computacao"), 
    *profissional_2 = new ProfessionalRegister ("leticia", 3, 4, "engenheira", "metalurgia"); 
    Register *pessoal =  new PersonalRegister ("Amanda" , 5, 6, "Rua", 7);
    agenda.insercao(profissional_1);
    agenda.insercao(pessoal);
    agenda.insercao(profissional_2);

    std :: cout << agenda.obter_cadastro(0)->get_nome() << std :: endl;
    std :: cout << agenda.obter_cadastro(0)->get_idade() << std :: endl;
    std :: cout << agenda.obter_cadastro(0)->get_cpf() << std :: endl;
    agenda.obter_cadastro(0)->get_atributos_extras();

    std :: cout << agenda.obter_cadastro(2)->get_nome() << std :: endl;
    std :: cout << agenda.obter_cadastro(2)->get_idade() << std :: endl;
    std :: cout << agenda.obter_cadastro(2)->get_cpf() << std :: endl;
    agenda.obter_cadastro(2)->get_atributos_extras();



    delete profissional_1;
    delete profissional_2;
    delete pessoal;
}

agenda.cpp:

#include "agenda.h"
#include <stdexcept>
#include <iostream>
#include <typeinfo>

Agenda :: Agenda(int capacidade){
    _num_cad = 0;
    _cadastros.resize(capacidade);  
}

Agenda :: ~Agenda(){

}

void Agenda :: insercao(Register *inserir){
    try {
        _cadastros.at(_num_cad) = inserir;
        _num_cad++;
    }
    catch (std :: out_of_range &e){
        std :: cerr << "out_of_range" << std :: endl;
    }
}

Register* Agenda :: obter_cadastro(int posicao){
    try {
        return _cadastros.at(posicao);
    }
    catch(std :: out_of_range &e){
        std :: cout << e.waht() << std :: endl
    }
}

error: Segmentation fault (core dumped)

I'm a new programmer and i dont know how to solve this, can anyone help me?

Upvotes: 0

Views: 48

Answers (1)

JHBonarius
JHBonarius

Reputation: 11281

You should start using a debugger to follow the code and see what's happening while executing it.

But IMHO you are using exceptions the wrong way around. You should not force an exception, which you catch to print an error. You should throw an exception when your function gets input it was not designed for. E.g.

Register const* GetAppointment(size_t nr) const {
    if (nr < appointments.size()) {
        return appointments[nr];
    } else {
        throw std::out_of_range("Appointment number out of range.");
    }
}

And please note the existence of std::unique_ptr, which handles all the creating and deletion of objects on the heap for you. Your whole code could look something like this:

#include <string>
#include <sstream>

class Register{
private:
    std::string name;
    int idade, cpf;
public:
    Register(std::string_view const& name, int idade, int cpf) : name(name), idade(idade), cpf(cpf) {}
    virtual ~Register() {}
    std::string const& GetName() const { return name; }
    int GetIdade() const { return idade; }
    int GetCpf() const { return cpf; }
    virtual std::string GetExtraAttributes() const = 0;
};

class ProfessionalRegister final : public Register {
private:
    std::string function;
    std::string speciality;
public:
    ProfessionalRegister(std::string_view const& name, int idade, int cpf
        , std::string_view const& function, std::string_view const& speciality)
        : Register(name, idade, cpf)
        , function(function), speciality(speciality) {}
    std::string GetExtraAttributes() const override {
        std::stringstream out;
        out << "Function : " << function << ", Department " << speciality;
        return out.str();
    }
};

class PersonalRegister final : public Register {
private:
    std::string street;
    int number;
public:
    PersonalRegister(std::string_view const& name, int idade, int cpf
        , std::string_view const& street, int number)
        : Register(name, idade, cpf)
        , street(street), number(number) {}
    std::string GetExtraAttributes() const override {
        std::stringstream out;
        out << "Street : " << street << ", number " << number;
        return out.str();
    }
};

#include <vector>
#include <memory>
#include <iostream>
#include <stdexcept>

class Agenda {
private:
    size_t nrOfAppointments{ 0 };
    std::vector<std::unique_ptr<Register>> appointments;
public:
    Agenda(size_t capacity) : appointments(capacity) {}
    void Add(std::unique_ptr<Register>&& reg) {
        if (nrOfAppointments < appointments.size()) {
            appointments[nrOfAppointments++] = std::move(reg);
        } else {
            std::cout << "Failed adding appointment: agenda full.\n";
        }
    }
    Register const* GetAppointment(size_t nr) const {
        if (nr < appointments.size()) {
            return appointments[nr].get();
        } else {
            throw std::out_of_range("Appointment number out of range.");
        }
    }
};

int main() {
    Agenda agenda(2);
    agenda.Add(std::make_unique<ProfessionalRegister>("camila", 1, 2, "engenheira", "computacao"));
    agenda.Add(std::make_unique<ProfessionalRegister>("leticia", 3, 4, "engenheira", "metalurgia"));
    agenda.Add(std::make_unique<PersonalRegister>("Amanda", 5, 6, "Rua", 7));

    std::cout << agenda.GetAppointment(0)->GetName() << '\n';
    std::cout << agenda.GetAppointment(0)->GetIdade() << '\n';
    std::cout << agenda.GetAppointment(0)->GetCpf() << '\n';
    std::cout << agenda.GetAppointment(0)->GetExtraAttributes() << '\n';

    std::cout << agenda.GetAppointment(2)->GetName() << '\n'; // throws an exception
    std::cout << agenda.GetAppointment(2)->GetIdade() << '\n';
    std::cout << agenda.GetAppointment(2)->GetCpf() << '\n';
    std::cout << agenda.GetAppointment(2)->GetExtraAttributes() << '\n';
}

Upvotes: 1

Related Questions