The Shed is going Social! Join us on FaceBook and Twitter and chime in on the conversation.
|
 |
|
Dev Shed Forums
> Programming Languages
> C Programming
|
Re: problem initiating objects of class
Discuss Re: problem initiating objects of class in the C Programming forum on Dev Shed. Re: problem initiating objects of class C programming forum discussing all C derivatives, including C#, C++, Object-C, and even plain old vanilla C. These languages are low level languages, and used on projects such as device drivers, compilers, and even whole computer operating systems.
|
|
 |
|
|
|
|

Dev Shed Forums Sponsor:
|
|
|

April 14th, 2003, 07:43 AM
|
|
Contributing User
|
|
Join Date: Feb 2003
Posts: 149
  
Time spent in forums: 1 Day 2 h 26 m 42 sec
Reputation Power: 13
|
|
|
Re: problem initiating objects of class
Can anyone please offer some advice what the following error message means:
college.cc: In function `int main(int, char**)':
college.cc:59: pointer to a function used in arithmetic
college.cc:59: request for member `setName' in `*(pupilnames() + (+i))',
which is of non-aggregate type `std::vector<Pupil, std::allocator<Pupil>
> ()()'
the lines in my program which this error occurs are:
vector <Pupil> pupilnames(); // line 45
string name; // line 47
int i; // line 49
while (!inFile.eof ()) // line 51
{ // line 52
if (!inFile.fail ()) // line 54
{ // line 55
inFile >> name; // line 57
pupilnames[i].setName(name); // line 59
i++; // line 61
} // line 62
} // line 63
Hope this is enough to get an idea what the problem is!
|

April 14th, 2003, 09:42 AM
|
 |
Contributing User
|
|
Join Date: Jan 2003
Location: USA
|
|
I learned my C++ pre-STL, so I'll ask a stupid question that might point you in the right direction.
When you create a vector of objects, does that vector end up containing instances of that object, or does it contain pointers to instances of the object?
In other words, should line 59 instead be:
Code:
pupilnames[i]->setName(name);
|

April 14th, 2003, 11:12 AM
|
|
Contributing User
|
|
Join Date: Feb 2003
Posts: 149
  
Time spent in forums: 1 Day 2 h 26 m 42 sec
Reputation Power: 13
|
|
|
My vector is supposed to create instances of the object rather than pointers and anyway even if I use pointers as in your code, I still get the error message shown on the previous post.
|

April 14th, 2003, 02:12 PM
|
 |
not a fan of fascism (n00b)
|
|
Join Date: Feb 2003
Location: ct
|
|
|
try sticking std:: in front of vector when u declare one. i remember having similar problems on a project i worked on.
|

April 14th, 2003, 02:26 PM
|
 |
Contributing User
|
|
Join Date: Jan 2003
Location: USA
|
|
Again, I don't have the experience with STL, but look at the second error message:
Quote:
college.cc:59: request for member `setName' in `*(pupilnames() + (+i))',
which is of non-aggregate type `std::vector<Pupil, std::allocator<Pupil>
> ()()'
|
I assume that your Pupil class has been declared properly, so why does the compiler think that it is a non-agregate type?
In Googling on this problem, I see other examples declaring the vector differently; eg:
What happens with you leave the parentheses out in line 45?
Quote:
vector <Pupil> pupilnames; // line 45
// instead of vector <Pupil> pupilnames(); // line 45
|
Had you created a vector of constructors by mistake? That could tie in with the error message complaining about a function pointer.
Also, I anticipate that you will have a runtime error. I would think that the vector would be empty when first created and that you will need to instantiate a Pupil before you can call its SetName() method and add it to the vector either before or after the SetName(), which would affect how you write it.
|

April 14th, 2003, 02:31 PM
|
|
Contributing User
|
|
Join Date: Feb 2003
Posts: 149
  
Time spent in forums: 1 Day 2 h 26 m 42 sec
Reputation Power: 13
|
|
|
Yes, your right it does appear that by removing the parenthesis, the error disappears. I've only had experience in using vectors of a pre-determined size and was not aware that if you want to leave the size of the vector open ended, all you had to do is remove the parenthesis.
You are right to believe that the vector is initially empty and that I want to create a vector of constructors for the class Pupils. How would I modify the line so that this is what happens? I have tried:
pupilnames.push_back (name);
but recieve the error message:
task4driver.cc: In function `int main(int, char**)':
task4driver.cc:57: no matching function for call to `std::vector<Pupil,
std::allocator<Pupil> >::push_back(std::string&)'
/usr/local/include/c++/3.1.1/bits/stl_vector.h:490: candidates are: void
std::vector<_Tp, _Alloc>::push_back(const _Tp&) [with _Tp = Pupil, _Alloc
= std::allocator<Pupil>]
Any ideas?
Last edited by markb_1984 : April 14th, 2003 at 02:48 PM.
|

April 14th, 2003, 05:02 PM
|
 |
Contributing User
|
|
Join Date: Jan 2003
Location: USA
|
|
Judging from the prototype in stl_vector.h (which is included by vector.h), pupilnames.push_back is looking for a reference to an object of class Pupil, so of course it's going to complain when you try to feed it a string instead.
You will need to instantiate a Pupil, call its SetName method, then push it into pupilnames, something like:
Code:
{
Pupil pupil();
pupil.SetName(name);
pupilnames.push_back(pupil);
}
Please note that pupil's scope is limited to the code block it's declared in and that it will be destroyed as soon as you leave the code block. I am assuming that a vector will make its own copy of whatever is passed to it and that the original object can safely be destroyed.
Or if it's more your style, declare a pointer to Pupil, construct an object with new, call SetName, dereference the pointer in the call to push_back, and delete the object:
Code:
Pupil *pupil;
pupil = new Pupil();
pupil->SetName(name);
pupilnames.push_back(*pupil);
delete pupil;
|

April 15th, 2003, 03:56 AM
|
|
Contributing User
|
|
Join Date: Feb 2003
Posts: 149
  
Time spent in forums: 1 Day 2 h 26 m 42 sec
Reputation Power: 13
|
|
|
My input file is as follows:
Kevin 20 42
Lee 60 58
The lines which I am using to read in the data of this file and then output it on screen making use of the pupil class are:
vector <Pupil> pupilnames;
string name;
int i=0, m1w, m1m;
while (inFile)
{
if (!inFile.fail())
{
inFile >> name, m1w, m1m;
Pupil *pupil;
pupil = new Pupil();
pupil->setName(name);
pupilnames.push_back (*pupil);
delete pupil;
pupilnames[i].setmodule1Weight(m1w);
pupilnames[i].setmodule1Mark(m1m);
i++;
}
}
for (int i = 0; i < 2; i++)
{
cout << pupilnames[i].getName() << endl
<< pupilnames[i].getmodule1Weight() << endl
<< pupilnames[i].getmodule1Mark() << endl;
}
Allthough this code compiles and the program executes ok, the problem is that unexpected results are produced.
What I wanted to happen was to create a loop which would go to the first line of the file and read in the name (Kevin), m1w (20), m1m (42). Then using the vector, a constructor would then be created assigning the variable name (Kevin) as the name of the constructor. Then using the mutator/set methods of the class, the variables m1w and m1m should then be stored in the object 'Kevin'. I then intended that the loop would proceed in doing the same on all subsequent lines of the file until no more lines were left (!inFile.eof()). Instead when I run this program, I get the following output:
Kevin
134514273
1073766787
20
134514273
1073766787
42
134514273
1073766787
This to me looks like instead of each iteration of the loop going to the next line and reading in the appropriate data and assigning them to the variables, what I think is happening is that on each oteration, the loop goes to the next word of the file and then assigns it to the name variable, but since the loop only looks at one word at a time, the other two variables don't get assigned to anything therefore producing garbage values upon output.
Seems to me to me that the problem is therefore related to the while loop although could easily be something else causing the problem.
Thoughts kindly appreciated.
|

April 15th, 2003, 04:39 AM
|
|
Contributing User
|
|
Join Date: Feb 2003
Posts: 149
  
Time spent in forums: 1 Day 2 h 26 m 42 sec
Reputation Power: 13
|
|
Solved it! The problem was the line:
inFile >> name, m1w, m1m;
Should have read:
inFile >> name >> m1w >> m1m;
Since writing this post, I've encountered another problem of which I would very much appreciate your advice.
I've now got a vector of constructors with loops to store in the attributes of each object.
I would now like to sort the vector using bubble sort so that the first pupil in the vector corresponds to the pupil obtaining the highest overall mark.
This is the code I'm using:
for (int i = 0; i < (pupilnames.size () - 1); i++)
{
for (int j = 0; j < (pupilnames.size () - 1); j++)
{
if (pupilnames[j].getfinalMark () > pupilnames[j + 1].getfinalMark ())
{
string temp = pupilnames[j].getName();
pupilnames[j] = pupilnames[j + 1]; // Line 90
pupilnames[j + 1] = temp; // Line 91
}
}
}
When compiling, I get the following error message:
task4dr.cc: In function `int main(int, char**)':
task4dr.cc:91: no match for `Pupil& = std::string&' operator
task4dr.cc:90: candidates are: Pupil& Pupil:  perator=(const Pupil&)
The error message indicates lines 90 and 91 to be the problem, and these have been commented show you can see which lines they refer to.
Thanks in advance.
Last edited by markb_1984 : April 15th, 2003 at 05:58 AM.
|

April 15th, 2003, 09:59 AM
|
 |
Contributing User
|
|
Join Date: Jan 2003
Location: USA
|
|
Quote: Originally posted by markb_1984
...
Pupil *pupil;
pupil = new Pupil();
pupil->setName(name);
pupilnames.push_back (*pupil);
delete pupil;
pupilnames[i].setmodule1Weight(m1w);
pupilnames[i].setmodule1Mark(m1m);
|
You will want to keep your style consistent. You should call all three methods the same way. Either call all three methods as you call setName and then push pupil into the vector, or push pupil into the vector and then call all the methods as you call setmodule1Weight.
Also, be sure that you understand what each line of code is doing well enough to be able to explain it. A good example is for you to explain why you are passing *pupil to push_back.
|

April 15th, 2003, 10:15 AM
|
 |
Contributing User
|
|
Join Date: Jan 2003
Location: USA
|
|
Quote: Originally posted by markb_1984
string temp = pupilnames[j].getName();
pupilnames[j] = pupilnames[j + 1]; // Line 90
pupilnames[j + 1] = temp; // Line 91
}
}
}
When compiling, I get the following error message:
task4dr.cc: In function `int main(int, char**)':
task4dr.cc:91: no match for `Pupil& = std::string&' operator
task4dr.cc:90: candidates are: Pupil& Pupil: perator=(const Pupil&)
|
Think about what you are doing. You want to have two Pupil objects swap places in the vector. What your code appears to be trying to do is to swap the names of the Pupil objects without moving any of the rest of the data.
Make temp a Pupil object and assign pupilnames[j] to it.
BTW, the compile error was because you were trying to assign a string to a Pupil. If you really wanted to change that Pupil's name, you should have used the setName method.
It's been a while since I've done the bubble sort, but your use of the indices don't look right to me. You need to play computer here -- test out your code by executing it yourself with pencil and paper. Create a short list on paper and run through it through your bubble sort by hand.
|
Developer Shed Advertisers and Affiliates
| Thread Tools |
Search this Thread |
|
|
|
| Display Modes |
Rate This Thread |
Linear Mode
|
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
|
|