Re: noobs and pointers
On Apr 13, 8:37 pm, "Randy" <gast...@sympatico.ca> wrote:
Hi,
I am a noob. I am trying to store Student objects pointers, in a
vector, within a School object.
In my opinion, you should be storing Students, not pointers to
Students.
I call a setter function to add the pointer. If I use this method it
works,
Student st = Student("Randy");
Student * stp = & st;
sc.addStudent(stp);
My problem is passing a Student to the School function. I have an
overridden function. I try to create a pointer from the passed
Student. I bet that's my problem because it's a copy ?
Its a copy alright, a copy of a pointer actually, unfortuanately -
copying pointers does not copy its pointee. And having a pointer to an
object does not guarentee that the object continues to exist.
This may sound a little strange to you right now but its fundamental
in C++. A dumb pointer is just a dumb pointer.
This all came about because I want to have a more succinct method for
doing this, just like the big kids do:
Student st = Student("Randy");
Student * stp = & st;
sc.addStudent(stp);
I've read lots but am apperantly missing the point. I am referencing
the C++ Primer.
here's my output too ... 2 Bills ?? ahaha ...
Schools Constructor 1
Student Constructor2 Randy
Overload addStudent1()
Student Constructor2 Biff
Overload addStudent3()
Stop right here. This should be your first clue. Take a look at that
member function:
void School::addStudent(Student n ){
cout << "Overload addStudent3()" << endl;
Student * s = & n;
mStudents.push_back(s);
}
You are storing pointers and yet parameter (Student n) ceases to exist
once the above member function terminates. Dumb pointer points to a
Student that is no longer.
The term is: dangling pointer
The result is: undefined behaviour
Student Constructor2 Bill
Overload addStudent1()
*** List ***
1 Randy
3 Bill
3 Bill
*** EOF ***
Press any key to continue . . .
main.cpp
---------------------------------------------------------------------------------------
#include <cstdlib>
#include <iostream>
#include <vector>
// #include "Templates.h"
// #include "PointersAndReference.h"
#include "StudentsAndSchools.h"
using namespace std;
int main(int argc, char *argv[])
{
// mypair<int> ok(10,23); // Declare an INT class w/
construction
// ok.printValues();
// referenceTests();
School sc;
sc.setNames("Parkside");
Student st = Student("Randy");
Student * stp = & st;
sc.addStudent(stp);
sc.addStudent(Student("Biff"));
Student st1 = Student("Bill");
Student * stp1 = & st1;
sc.addStudent(stp1);
sc.getStudentNames();
system("PAUSE");
return EXIT_SUCCESS;
}
--------------- StudentsAndSchools.h
-------------------------------------------------------------
#ifndef __StudentsAndSchools__
#define __StudentsAndSchools__
Underscore + Capitale letter is reserved
2 Underscores + whatever is also reserved
#ifndef StudentsAndSchools_h
#define StudentsAndSchools_h
Although Student should have its own header and School ditto
using namespace std;
Using directives in a header file is a very bad idea.
class School;
class Student {
private:
static int mLastId;
string mName;
int mId;
School * mSchool;
public:
Student(){
cout << "Student Constructor1" << endl;
}
Student(string n){
cout << "Student Constructor2 " << n << endl;
mName = n;
mId = ++mLastId;
}
Initialize non-static members using an init list.
Student(std::string n) : mName(n), mId(++mLastId)
{
cout << "Student(std::string n) " << n << endl;
}
void setName(string n);
void setName(const std::string&);
string getName();
std::string getName() const;
int getId();};
int getId() const;
int Student::mLastId = 0;
string Student::getName(){ return mName; };
int Student::getId(){ return mId; };
class School{
private:
string mName;
vector<Student*> mStudents;
public:
School(){
cout << "Schools Constructor 1" << endl;
}
void addStudent(Student* );
void addStudent(Student &); // overloaded
function
// the key is the constant keyword, the only version you need is by
const reference
void add(const Student&);
// the next "overload" prevents the former from being called although
the compiler should be generating a diagnostic about a conflict (which
one of these "overloads" should it call?).
void addStudent(Student);
void setNames(string n);
void getStudentNames();
const qualifiers missing above
<snip>