Cannot add objects to a template vector

Hello Everyone,

while writing a Library management application I run into a problem, that I can't find any solution to.

I have a template class 'Database.hpp' that holds a vector and a few methods, which I can do some basic file operations like save-to and read-from a *.txt file.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59

//Database.hpp
#pragma once

#include "Reader.h"
#include <conio.h>
#include <string>
#include <vector>

template<class T>
class Database
{
	std::vector<T> database;

public:

	void add(const T obj)
	{
		database.push_back(obj);
	}

	void save_records(const std::string filename)
	{
		std::ofstream fout;

		fout.open(filename, std::ios::trunc);

		fout << database.size() << std::endl;

		for (auto& obj : database)
			fout << obj;

		fout.close();
	}

	void read_records(const std::string filename)
	{
		std::ifstream fin;
		
		fin.open(filename);
		
		int no_of_records;

		fin >> no_of_records;

		fin.ignore();

		for (int i = 0; i < no_of_records; i++)
		{
			T obj;

			fin >> obj;

			add(obj);
		}
		fin.close();
	}
};


Next, in my Application.hpp class I'm initializing the instance of Database. By doing so I want to have access to vector (the getter is located in the *.cpp file) and make use of the methods, that are available in Database.hpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
//Application.hpp
#pragma once

#include "Database.hpp"
#include "Reader.h"
#include <fstream>
#include <string>
#include <vector>

class Application
{
	const std::string READERS_DATABASE;

	Database<Reader> READERS;

public:

	Database<Reader> get_Readers();
	
	Application() : 
		READERS_DATABASE("READERS_DB.txt") 
	{}
	
	void initialize()
	{
		READERS.read_records(this->READERS_DATABASE);
	}

	void save_records()
	{
		READERS.save_records(this->READERS_DATABASE);
	}

};

//Application.cpp

#include "Application.hpp"

Database<Reader> Application::get_Readers()
{
	return Database<Reader>();
}


Finally, I have my Interface.h and Interface.cpp class, where I'm calling the instance of Application.hpp. Here I'm also initializing the vector called READERS and attempting to add an object of type Reader. When closing the application the objects in my vector are saved to the *txt file.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
//Interface.h

#pragma once

#include "Application.hpp"
#include "Database.hpp"
#include "Reader.h"
#include <string>

class Interface
{
	char choice;
	std::string fisrtname, lastname, address, birth_date, pesel;

	Application App;

public:

	void Main_Menu_Panel();
	void Add_Reader_Panel();
	void Delete_Reader_Panel();
	void Display_Panel();
	void Report_Panel();
	Interface();
};


//Interface.cpp

#include "Application.hpp"
#include "Database.hpp"
#include "Interface.h"
#include "Reader.h"
#include <iostream>
#include <conio.h>
#include <string>

Interface::Interface()
{
	App.initialize();
}

void Interface::Main_Menu_Panel()
{
	system("CLS");
	std::cin.clear();
	std::cout << "***** SOCRATES Library System (alpha) ***** \n \n";
	std::cout << "\t 1. Add new reader \n";
	std::cout << "\t 2. Delete reader \n";
	std::cout << "\t 3. Display \n";
	std::cout << "\t 4. Reports \n";
	std::cout << "\t 0. Exit \n \n";

	std::cout << "\t ------------------ \n \n";
	std::cout << "\t Choose: ";
	std::cin >> choice;
	std::cout << std::endl;

	switch (choice)
	{
	case '0': App.save_records();
		exit(0);
	case '1': Add_Reader_Panel();
	case '2': Delete_Reader_Panel();
	case '3': Display_Panel();
        case '4': Report_Panel();
	default: break;
	}
}

void Interface::Add_Reader_Panel()
{
	while (true)
	{
		system("CLS");
		std::cin.clear();
		std::cout << "\t ***** SOPHOCLES Library System (alpha) ***** \n \n";
		std::cout << "\t Please fill in the information: \n \n";
		std::cout << "\t Firstname: \t"; std::cin >> fisrtname;
		std::cout << "\t Lastname: \t"; std::cin >> lastname;
		std::cout << "\t Address: \t"; std::cin >> address; 
		std::cout << "\t Birth date: \t"; std::cin >> birth_date;
		std::cout << "\t Pesel: \t"; std::cin >> pesel;

		Reader r(fisrtname, lastname, address, birth_date, pesel);

		App.get_Readers().add(r);

		std::cout << "\n";
		std::cout << "\t ------------------ \n \n";
		std::cout << "\t Save and exit? (Y/N): ";
		std::cin >> choice;

		if (choice == 'y' || choice == 'Y')
		{
			break;
		}
	}
	Main_Menu_Panel();
}

//main.cpp

#include "Interface.h"
#include <iostream>

int main()
{
	Interface I;
	
	I.Main_Menu_Panel();

	return 0;
}


The problem I'm having is, that when I'm adding the Reader object through 'App.get_Readers().add(r)' the vector seems to be empty in the end (that is, when I'm closing the app, the txt file shows '0'). I cannot figure out why that is happening.

I am sorry if I made this post very long and confusing, but that's the best way to describe the problem I'm facing.
I'm also new to C++ so I ask for your undestanding.

I really really appreciate your help on this.
Adrian


Last edited on
get_Readers() returns a copy/temporary object that is dismissed after the add(...) function is done.

To make it work you need to return a reference to the member variable:
1
2
3
4
Database<Reader>& Application::get_Readers() // Note: &
{
	return READERS;
}
Topic archived. No new replies allowed.