So I have an exercise in C++. I have a structure student with the following members: 1 int, 2 char, 1 float and (I write the lines from the exercise): "two pointers on functions for reading data void (*read)(student*st) and one pointer for displaying data void (*write)(student*st) "
I have to read from keyboard the number of students and then to allocate memory for an array with students.
Then I have to define 2 functions: void readData(student* st) and void writeData(student* st) which read and display the members of one student structure. I have to go through students array and to initialize the pointers to functions void (*read)(student*st) and void (*write)(student*st) with void readData(student* st) and void writeData(student* st). Here I am a little bit confused.
The last thing I need to do is to go through students array and to call the functions v[i].read(&v[i]) and v[i].write(&v[i]) to read and display data.
First, a suggestion: n should not a parameter of your readStudents function, because you only use it as a local variable. Just declare the variable locally within the function.
1 2 3 4
void readStudents() {
int n;
// ...
}
or, ask for user input via cin >> in main, and then pass the n value, but don't ask again within your function.
Additionally, you used new[] to allocate an array, but you never called delete[] on that memory. You have a memory leak. Consider using std::vector in the future; it is essentially an array but will manage the memory for you.
To assign to a variable that holds a function pointer, you'd do something like:
struct Student {
int age;
std::string name;
void (*DoWork)(Student* student) = nullptr;
staticvoid (*Info)(Student* student); // Caution: The function assigned will be shared by ALL instances of Student
// Caution: This is a declaration. You must provide a definition for the function pointer.
// See https://stackoverflow.com/a/24622465/3396951
};
// Define the function pointer for Student class; Here it's initialized to nullptr.
// Remember to initialize the class function pointer before invoking it!
void (*Student::Info)(Student* student) = nullptr;
void DoMath(Student* student)
{
std::cout << student->name << ": Doing Math. y=mx+b.\n";
}
void DoPhysics(Student* student)
{
std::cout << student->name << ": Doing Physics. E=mc^2.\n";
}
void DoHistory(Student* student)
{
std::cout << student->name << ": Doing History. ZZZzzzz.\n";
}
void ShowFullInfo(Student* student)
{
std::cout << "ShowFullInfo: Student Name: " << student->name << "\n";
std::cout << "ShowFullInfo: Student Age: " << student->age << "\n";
}
void ShowName(Student* student)
{
std::cout << "ShowName: Student Name: " << student->name << "\n";
}
void InitStudentsArray()
{
Student classroom[3]; // An array of 3 Student objects
// Initialize members of each Student object
classroom[0].name = "Alice";
classroom[0].age = 20;
classroom[1].name = "Bob";
classroom[1].age = 21;
classroom[2].name = "Cathy";
classroom[2].age = 22;
// Initialize each Student's function pointer (the work they do)
classroom[0].DoWork = DoMath;
classroom[1].DoWork = DoPhysics;
classroom[2].DoWork = DoHistory;
// Invoke the function pointer
classroom[0].DoWork(&classroom[0]);
classroom[1].DoWork(&classroom[1]);
classroom[2].DoWork(&classroom[2]);
// Alice now decides to do history
classroom[0].DoWork = DoHistory;
classroom[0].DoWork(&classroom[0]);
// Specify that the class method should display the name and age of each student
Student::Info = ShowFullInfo;
Student::Info(&classroom[0]); // Calls ShowFullInfo(Alice)
Student::Info(&classroom[2]); // Calls ShowFullInfo(Cathy)
// Reassign what the class method should do; in this case, only display the name of the student passed as the argument
Student::Info = ShowName;
Student::Info(&classroom[0]); // Calls ShowName(Alice)
Student::Info(&classroom[2]); // Calls ShowName(Cathy)
// You can't return classroom since it's a local array
}
Output:
1 2 3 4 5 6 7 8 9 10
Alice: Doing Math. y=mx+b.
Bob: Doing Physics. E=mc^2.
Cathy: Doing History. ZZZzzzz.
Alice: Doing History. ZZZzzzz.
ShowFullInfo: Student Name: Alice
ShowFullInfo: Student Age: 20
ShowFullInfo: Student Name: Cathy
ShowFullInfo: Student Age: 22
ShowName: Student Name: Alice
ShowName: Student Name: Cathy
This should show you how to assign a function to a function pointer and how to invoke the function pointer. DoWork() makes more sense as a member function to avoid passing the address of each Student.
The read and write function pointers look like they should be static (unless there is a reason you need each Student object to specify a different behavior of read/write).