1

I have a question that I am battling to get my head around. I am given a struct:

struct Module
{   
    string moduleName;
    string moduleCode;
    string lecturer;
    string nrStudents;
}

and I am asked to do the following:

  1. Turn the struct into a class
  2. Make all member variables private
  3. Include public member functions for each of the following
    • a default constructor that sets the string member variables to blank strings and int to 0.
    • an overloaded constructor that sets the string member variables to specific values.
    • member functions to set each of the member variables to a value given as an argument to the function i.e. mutators.
    • member functions to retrieve the data from each of the member variables i.e. accessors.

Test the class in a program that instantiates an object of class Module (i.e. ‘declare’ an object of ‘type’ Module). The program should then input values for the object (obtained from the keyboard), and use the mutators to assign values to the member variables. Use the accessors to obtain the values of the member variables of the object and display those values on the screen. Test your program with the following input:
Input for member variables of Module object:

Here is my code so far:

Module name: Introduction to Programming
Module code: CSS1515
Lecturer: Mrs Smith
Number of students: 250

#include <iostream>
#include <cstdlib>
using namespace std;

class module
{
 private:
    string moduleNameVar;
    string moduleCodeVar;
    string lecturerVar;
    int nrStudentsVar;

public:
    module( );
    //initializes moduleName, moduleCode and lecturer to a blank string
    //initializes nrStudent to 0
    module(string moduleName, string moduleCode, string lecturer, int nrStudents);
    //initializes moduleName, moduleCode and lecturer to a string value
    //initializes nrStudent to a number of students
    void set(string moduleName, string moduleCode, string lecturer, int nrStudents);
    //sets the moduleName, moduleCode, lecturer and nrStudents
};

int main()
{
    module exam1("Introduction to Programming","COS1515","Mrs Smith", 250);
}
    module::module( ) : moduleNameVar(""), moduleCodeVar(""), lecturerVar(""),     nrStudentsVar(0)
{
    //body intentionally empty
}

    module::module(string moduleName, string moduleCode, string lecturer, int nrStudents)
{
    module::set();
}

    void module::set(string moduleName, string moduleCode, string lecturer, int nrStudents)
{
    moduleNameVar = moduleName;
    moduleCodeVar = moduleCode;
    lecturerVar = lecturer;
    nrStudentsVar = nrStudents;
}

Now what I am trying to understand is why I am asked to use mutators when I've already defined a constructor which could effectively set my member variables. Nonetheless, I am trying to achieve this using: module::set();, but this is throwing up an error in the compiler: no function for call to module::set()

What am I missing here? How do I go about creating the mutator functions as well as the constructor function?

Note: The accessor function seems easy enough as I would merely be using a get() function to access the member variables?

Cœur
  • 37,241
  • 25
  • 195
  • 267
Metamorphosis
  • 95
  • 1
  • 1
  • 10

4 Answers4

1

Usually when you want to provide a constructor that sets the fields of an object you don't directly use setters but you initialize them in the initializer list, like you are doing for your empty constructor (unless you have some side effects or computations which you don't want to replicate).

In your case you declare a module::set method which accepts all the parameters to set values of a module but you invoke it without forwarding such values from the constructor to the set method. Indeed a set(void) method doesn't exist for the class and this raises a compilation error.

Then read the specification:

member functions to set each of the member variables to a value given as an argument to the function i.e. mutators

This means that you need a method to inizialize each of them, eg

void module::setName(const std::string& name) {
  this->name = name;
}

const std::string& getName() const {
  return this->name;
}
Jack
  • 131,802
  • 30
  • 241
  • 343
1

How do I go about creating the mutator functions as well as the constructor function?

Very simple, you simply add a public member function which takes an argument of the appopriate type, and sets the variable to its value. For example, the mutator for module name should look something like this:

void setModuleName(const string &name){ 
  moduleNameVar = name; 
}

Then similar functions for the others.

The accessors will just return the value of the member variable from your class. For example:

std::string getModuleName() const{ return moduleNameVar; }

and similar functions for the others. The 'const' at the end of the function declaration indicates that using this function won't change the value of anything within your class (it's not strictly necessary but is good practise to include).

Nonetheless, I am trying to achieve this using

module::set();

but this is throwing up an error in the compiler "no function for call to 'module::set()'

You haven't defined a function that matches the one you're trying to use. You've only defined

module::set(string moduleName, string moduleCode, string lecturer, int nrStudents) 

which has four arguments, and no default values for any of those arguments. But you're trying to use it without any arguments - the compiler has no way of knowing what you want it to do in that case, and so it gives the error.

Community
  • 1
  • 1
Chris H
  • 790
  • 9
  • 19
0

You should write one mutator for each member variable, not one for all, e.g.:

void setName(const string &name)
{
  moduleNameVar = name;
}

And the reason mutators are useful even if you have a constructor is that you can use mutators whenever you like, not just when you construct the object.

Beta
  • 96,650
  • 16
  • 149
  • 150
0

First replace the body of your overloaded constructor with the module::set() function body:

module::module(string moduleName, string moduleCode, string lecturer, int nrStudents)
{
    moduleNameVar = moduleName;
    moduleCodeVar = moduleCode;
    lecturerVar = lecturer;
    nrStudentsVar = nrStudents;
}

and delete your module::set() method declaration and definition.

Next, add "getter" and "setter" methods for each of the fields. So, one method to get moduleName, and one to set it, etc..

Kenney
  • 9,003
  • 15
  • 21
  • Thanks for the input. I have managed to add my setter and getter methods. When it comes to my input from the keyboard, would it be better to do this in my main function or should I preferably write a function in public to pass each member variable to private? What is preferred as good programming practice in this regard? – Metamorphosis Sep 19 '15 at 14:36
  • A rule of fist is that no method may be longer than 1 page, since then you cannot see it's structure in one glance. I'm sure you'll learn about _top down_ and _bottom up_ programming and _breaking/violating abstraction_ later in your course. – Kenney Sep 19 '15 at 14:42
  • Cool, thanks for the advice... I'll look these concepts up. – Metamorphosis Sep 19 '15 at 19:12