Input storing with vector and pointers, help!

Hello!

So im doing this program where the user has to write
age, name, how many rooms the apartment has and what is the measurment.
And every person apartment has to be a pointer to the class apartment in the class Person.

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
  using namespace std;
class Person {
public:
	Person(string, string, int, Apartment*);
	string get_name() {
		return name;
	}
	string get_family() {
		return family;
	}
	int get_age() {
		return age;
	}
	
	Apartment* get_apartment() {
		return apartments;
	}
private:
	string name;
	string family;
	int age;
	Apartment* apartments;
};

class Apartment {
public:
	Apartment(int, double);
	int get_rooms() {
		return rooms;
	}
	double get_measurment() {
		return measurment;
	}

private:
	int rooms;
	double measurment;
	
};


int main()
{


	vector <Person> persons;
	

	string N, F;
	int A, R;
	double M;



	cout << "Please write your first name/last name/ age / number of rooms / measurment of apartment : " << endl;
	while (cin >> N >> F >> A >> R >> M) {
		Person tmpPerson(N, F, A, R, M);

		persons.push_back(tmpPerson);
	};
	
    return 0;
}

Person::Person(string n, string f, int a, Apartment* ap) {
	name = n;
	family = f;
	age = a;
	apartments = ap;
}
Apartment::Apartment(int r, double m) {
	rooms = r;
	measurment = m;
}



Sadly im getting " No instance for constructor "Person::Person" matches the argument lsit types are : (std::string, std::string, int, int , double)"

at Person tmpPerson(N, F, A, R, M) this part of the code.
I'm not sure its happening when , N = string, F = string, R= int, M= double;

Seems fine to me ? What could be the problem?

Also thanks in advance, this community is great !!!
Last edited on
closed account (SECMoG1T)
hello you are having argument parameter mismatch;

1
2
3
4
5
6
7
8
9
Person::Person(string n, string f, int a, Apartment* ap)///your cstor declaration
tmpPerson(N, F, A, R, M);///error in usage

string N, F;   int A, R;  double M;

your Cstor takes:    two strings, a single int  and a pointer to an Apartment
you are passing :    two strings,    two ints   and  a double

///do you see the mismatch now. 
Ahhh i seee.

Sadly i am not sure how i am suposed to write it properly.
I might even be using the wrong method to do what i want.

Any advice ?
Hello FreeSock,

Yolanda has pointed out the parameter mismatch between the call and the function declaration and definition.

The problem I see is that the overloaded ctor needs an address for the pointer, but you never create one before the "Person" ctor is called. So even if you fix the parameters to the ctor there is no address for the pointer.

Working on it and should have something in a bit.

Hope that helps,

Andy
closed account (SECMoG1T)
some advice
-you can have as many cstors as your program requires

-line 15: it is not very safe to return a raw pointer because as the original own might invalidate
it, you can return a copy of the object pointed to or a smart pointer(shared_ptr<>)

-line 37: am not sure if a single variable will suffice to hold your measurement, back here i could
store the measurement of a room in three variables {length,width,height}
1
2
3
4
5
6
7
               struct measurements
               {
                   double length;
                   double height;
                   double width;
              }; ///maybe
               


line 56: your loop there , clean it up a lil' ,you need a way out of the loop once you're done

line 59: after you have collected the data , am sure you need to use it somehow.
Thanks for the advices Andy and Yolanda!

The thing about the measurment is , its not the rooms measurment, but the square meters of the whole apartment. I just wrote it as measurment because i couldn't figure a better sounding variable. So basically they need to write 1 number like 120 square meters, 105 square meters etc. No need for lenght or height etc.

But you guys are right i did some sort of fix error, but then im getting all kind of erros like

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Severity	Code	Description	Project	File	Line	Suppression State
Error	C3861	'get_apartment': identifier not found	89	
Error	C2065	'apartments': undeclared identifier 81	
Error	C2597	illegal reference to non-static member 'Person::age'	80	
Error (active)	E0493	no instance of overloaded function "Person::Person" matches the specified type
Error (active)	E0350	more than one operator "<<" matches these operands:	89	
Error	C2061	syntax error: identifier 'Apartment'	12	
Error	C2143	syntax error: missing ';' before '*'	23	
Error	C4430	missing type specifier - int assumed. Note: C++ does not support default-int	23	
Error	C2334	unexpected token(s) preceding '{'; skipping apparent function body	23	
Error	C2143	syntax error: missing ';' before '*  31	
Error	C4430	missing type specifier - int assumed. Note: C++ does not support default-int		31	
Error	C2238	unexpected token(s) preceding ';'	31	
Error	C2661	'Person::Person': no overloaded function takes 4 arguments 65	
Warning	C4018	'<': signed/unsigned mismatch	69	
Error	C2511	'Person::Person(std::string,std::string,int,Apartment *)': overloaded member function not found in 'Person'	77	
Error	C2597	illegal reference to non-static member 'Person::name'	78	
Error	C2597	illegal reference to non-static member 'Person::family'  79	 


So many errors ,im clearly using pointes with classes in this case the wrong way. Not sure how to even make it work ;/`

EDIT : Withouth the pointer and the apartment pointer it works fine.. I just need some guidance how to make it work with it. So confusing
Last edited on
Hello FreeSock,

I did manage to get the code to compile and work.

Along with what Yolanda said I changed the first cout statement to:
 
std::cout << "\n Please write your:\n   first name\n   last name\n   age\n   number of rooms\n   measurment of apartment\n Enter each request with a space between each entry.\n The measurement is in square meters: ";

Sorry it turned out to be one long line. Give it a try and see what you think.

The only way out of the while loop is if you enter a non numeric value for a numeric variable.

Personally I like to set up where each variable has its own "cin" or other type of input. It is a little more work, but you can deal with validating or bad input one at a time instead of trying to figure out what went wrong. As it is you have five variables being entered at the same time and no way of knowing which one was a problem.

I would consider using "std::getline" for the string variables because a first or last name may have a space in it. Using the "std::cin >>" method would extract up to the first white space and stop leaving what is left in the input buffer. This would cause the next "cin" to extract from the buffer and not the keyboard. And that would eventually cause a problem with the numeric variables.

Once the strings are out of the way you can use "cin" for the rest of the variables. With the numeric variables you can follow the "cin" with:
1
2
3
4
5
6
7
while( !std::cin )
{
    std::cout << "Invalid input, try again: ";
    std::cin.clear();  // <--- Clears the state bits on "cin"
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');  // <--- Requires header file <limits>. Clears the input buffer
    std::cin >> numericVariable;
}

The while loop will continue until you enter a valid number.

I would likely replace the while loop with a do/while loop and at the bottom ask the user to continue entering or quit. This gives you a way out of the loop. A general idea of the code I like to use is:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <cctype>  // <--- for std::toupper, std::tolower and others.

char choice{};
bool cont{ true };

do
{
	// code here.

	std::cout << "\n Would you like to enter another? Y/N: ";
	std::cin >> choice;
	choice = std::toupper(choice);

	if (choice != 'Y')
		cont = false;
} while (cont);


Hope that helps,

Andy
closed account (SECMoG1T)
+Andy ...
alright i tried to clean you code some ... see if you would learn something.

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
115
116
117
#include <iostream>
#include <vector>
#include <string>

using namespace std;

class Apartment;

class Person {
  public:
	Person(string, string, int, Apartment*);
	string get_name();
	string get_family();
	int    get_age();
	Apartment* get_apartment();
	void   print();//added this
  private:
	string name;
	string family;
	int age;
	Apartment* apartments;
};



class Apartment {
  public:
	Apartment(int, double);
	int get_rooms();
	double get_dimension();

  private:
	int rooms;
	double dimension;
};

Person personCreate() ///helper function
{
  std::string _Family{},_Fstname{};
  int _Age=0,_Rooms=0;
  double _Dimens =0.0;

  std::cout<<"Enter your family     : "; std::cin>>_Family;
  std::cout<<"Enter your first name : "; std::cin>>_Fstname;
  std::cout<<"Enter your age        : "; std::cin>>_Age;
  std::cout<<"Enter # of rooms owned: "; std::cin>>_Rooms;
  std::cout<<"Enter the dimension of each room: "; std::cin>>_Dimens;

  Apartment *_Ap       =   new Apartment(_Rooms,_Dimens); ///create a pointer to an apartment
  Person     _TempPerson(_Fstname,_Family,_Age,_Ap);

  return _TempPerson;
}

int main()
{
   ///an example on usage
   Person _Me = personCreate();

          _Me.print();

    return 0;
}


/*******************************class Person defs***************************************/
Person::Person(string _name, string _family, int _age, Apartment* _apartmnt) ///let the parameters have some meaning
 :name(_name),family(_family),age(_age),apartments(_apartmnt) ///a constructor list init saves time
{
}

string Person::get_name()
{
   return name;
}

string Person::get_family()
{
  return family;
}

int Person::get_age()
{
  return age;
}

Apartment* Person::get_apartment()
{
  return apartments;
}

void Person::print()
{
    std::cout<<"\n{"<<name<<" "<<family<<"} "\
             <<age<<" years\n"\
             <<std::string(20,'*')<<"\n"\
             <<"rooms owned: "<<apartments->get_rooms()<<"\n"\
             <<"each room @: "<<apartments->get_dimension()<<" M2\n\n";

}

/****************************class Apartment defs *****************************************/
Apartment::Apartment(int _rooms, double _dimens)
:rooms(_rooms),dimension(_dimens)
{
}

double Apartment::get_dimension()
{
  return dimension;
}

int Apartment::get_rooms()
{
    return rooms;
}
Hey thanks for the help!

The thing is not the while loop though.

I know that its endless at this point and badly written i just wrote it so i can test the pointer.

What does not work is the pointer. I can't make it so that every person apartment has to be a pointer to the class apartment in the class Person.

I am unaware how to wroite it properly with pointers and classes together.
Hello FreeSock,

Your program as I changes things to get it to compile and run. Compare the differences. I made some comments through out the program.

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
// <--- Needs header files.

//using namespace std;  // <---Best not to use.

class Apartment;

class Person
{
	public:
		Person(std::string, std::string, int, int, double);  // <--- Changed parameter list.

		std::string get_name()
		{
			return name;
		}
		std::string get_family()
		{
			return family;
		}
		int get_age()
		{
			return age;
		}

		Apartment* get_apartment()
		{
			return apartments;
		}

	private:
		std::string name;
		std::string family;
		int age;
		int numRooms;
		Apartment* apartments;
};

class Apartment
{
	public:
		Apartment(int, double);
		int get_rooms()
		{
			return rooms;
		}
		double get_measurment()
		{
			return measurment;
		}

	private:
		int rooms;
		double measurment;

};

int main()
{
	std::vector <Person> persons;
	std::string N;
	std::string F;
	int A, R;
	double M;

	std::cout << "\n Please write your:\n   first name\n   last name\n   age\n   number of rooms\n   measurment of apartment\n Enter each request with a space between each entry.\n The measurement is in square meters: ";

	while (std::cin >> N >> F >> A >> R >> M)
	{
		Person tmpPerson(N, F, A, R, M);

		persons.push_back(tmpPerson);
	};

	return 0;
}

// *********************************************************************************

Person::Person(std::string n, std::string f, int a, int r, double m)  // <--- Changed parameter list.
{
	name = n;
	family = f;
	age = a;
	numRooms = r;  // <--- Added this before I realized it is not needed here.
	//apartments = ap;
}

Apartment::Apartment(int r, double m)
{
	rooms = r;
	measurment = m;
}


Andy
Hello FreeSock,

Just playing around and trying to keep with you want I came up with this:

1
2
3
4
5
6
7
8
9
10
11
12
13
	while (std::cin >> N)
	{
		if (N == "e") break;
		
		std::cin >> F >> A >> R >> M;

		temp = new Apartment(R, M);

		Person tmpPerson(N, F, A, temp);

		persons.push_back(tmpPerson);
	};


See if that helps,

Andy

P.S. Also changes the "Apartment" class:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Apartment : public Person
{
	public:
		Apartment(int, double);
		int get_rooms()
		{
			return rooms;
		}
		double get_measurment()
		{
			return measurment;
		}

	private:
		int rooms;
		double measurment;
};

Last edited on
Thanks you Yolandi and Andy for the help, both solutions were just great !

Trying to study them now and learn from then.

Love you guys ! <3
Topic archived. No new replies allowed.