0

Hi all I am in Intro to Programming and am a little unsure about member initialization and default constructors. We are learning the basics of classes and structures but we haven't even gotten to constructor methods or inheritance yet, so I'm a little ahead of the class. I surfed the web and I couldn't find an exact answer to my question so I figured I would ask here:

class ProductionWorker : public Employee
{
private:
int shiftNum;
double hourlyPay;

public:



//constructor for ProductionWorker
ProductionWorker(int newShiftNum, double newHourlyPay) : Employee(getEmpName(), getEmpNum())
{
    shiftNum=newShiftNum;
    hourlyPay=newHourlyPay;
}

In this snippet the first problem that I ran into was I was getting an error that there was no default constructor for the class Employee and after some research I found out that if a class is inheriting another class, the inherited class needs to have a default constructor. I read a little more into member initialization and from my understanding, I can do away with the need for a default constructor of an inherited class if I just have the ProductionWorker constructor initialize the Employee constructor.

Is this correct?

The arguments that are passed into the Employee constructor are "getters" because I can't directly pass in the variables held in the Employee class because they are private, would this cause unforeseen problems?

7
  • possible duplicate of Default constructor for an inherited class Commented Nov 15, 2013 at 23:13
  • 2
    Your bolded statement is correct -- you only need a default constructor if it's actually used. It appears, though, that you're trying to call getters from the base class (before its constructor is called!) in order to initialize the base class -- if this is the case, you're initializing memory with itself, which is uninitialized in the first place... Commented Nov 15, 2013 at 23:14
  • Calling getters of a class which is yet to be constructed.I dont think thats possible. Commented Nov 15, 2013 at 23:15
  • That helps a lot thanks, I was trying to get around having to declare the variables of the Employee class in public but I guess that's what I'll have to do. Commented Nov 15, 2013 at 23:17
  • @JtWeidenfeller: No, you don't have to do that, that's just silly. Commented Nov 15, 2013 at 23:17

3 Answers 3

2

Before you create a class, you cannot access its members. So Employee( getEmpName(), getEmpNum() ) makes no sense. You are supposed to pass those values into the constructor, and then later if you need them, call the accessors.

public ProductionWorker( string name, int num, int shiftNum, double pay ) :
    Employee( name, num )
{
    this->shiftNum = shiftNum;
    this->hourlyPay = pay;
}

Inheritance is a is a relationship. When you create a ProductionWorker you are also creating a Employee. Since Employee only has a constructor that takes a name and number (I assume), those are usually passed into ProductionWorker so it can create the Employee correctly. As Noted below, there are alternatives, but this seems like the logical way in this scenario.

Sign up to request clarification or add additional context in comments.

7 Comments

Those arguments don't necessarily have to be passed to the ProductionWorker constructor. They can be generated some other way, just not with members of the object itself. Though for this case, I see no sensible alternative.
When I try this I get an error because the variables inside the Employee class are private which is why I thought I could just use a getter. But you're right that doesn't make sense to use getters that aren't initialized. If I moved the variables from private to public it would work but I was under the assumption that data should always be private
It may compile, but it is undefined behavior. Maybe you want to pass an existing Employee into the ProductionWorker. ProductionWorker( Employee e, ... ) : Employee( e.getEmpName(), e.getEmpNum() ) {} but probably since you are creating a new Worker it is probably a new Employee all together
@BenjaminLindley true, this just seemed like this was the solution for the scenario.
This will work, but it's bad style for two reasons. One, assignment in the body when you could put members in the initializer list. Two, intentionally introducing naming conflicts.
|
1

Base class do not need to have a default constructor. If they do not have a default constructor, each constructor of a derived class needs to explicit call one of the base class constructors from its member initializer list. However, you shouldn't attempt to use any member functions because the object isn't constructed, yet. You basically want to use the constructor arguments of the derived class to determine which values you want to pass to the base class.

In your specific example it looks as if the Employee base class wants to get a name and an employee number. You might want to pass them to your derived class in addition to the information need only by the derived object.

Comments

0

You understend it correctly I think but you've missused a notion. Arguments of Employee class constructor can be it's setters, because they might allow you to set the private properties of base class.

A getter would allow you to get (no surprise) the value of private field.

By the way, constructor of inheriting class will always call the base class' constructors. Of course if the base class have constructor that accepts no arguments then there is no need to call it explicitly in inheriting class.

Imagine that you have classes:

class ColorCircle : public Circle{

string color;

ColorCircle (string c)
{
this.color = c;
}

}

and

class Circle {

double diameter;

Circle (double d)
{
this diameter = d;
}
}

If you want to create a ColorCircle you have to provide also the information about it's diameter but the constructor of ColorCircle does not have any place for this. Thats why constructor of ColorCircle should look like this:

ColorCircle (string c, double d) : Circle (d)
{
this.color = c;
}

And when you create a ColorCircle you just do:

new ColorCircle("red", 2.5);

The program takes care about passing the diameter value 2.5 to the proper base class constructor.

3 Comments

I was using using getters and not setters, my mistake I'm glad you caught that. That was exactly the problem that I was having is I was unable to use the variables of the Employee class because they were private. How would I pass in a value to the Employee constructor if I create ProductionWorker and the arguments of Employee are it's setters?
I hope you understand now. Some of arguments of ProductionWorker's constructor have to be passed to the base class (Employee's) constructor exactly like the double d was passed to the Circle's constructor in my example.
Yes I understand now, I was unaware that inheritance could work like that. thank you again

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.