Having trouble with const

This is a discussion on Having trouble with const within the C++ Programming forums, part of the General Programming Boards category; I had to modify this code to inlcude a const. When I did that, I keep getting three errors. This ...

  1. #1
    Registered User
    Join Date
    Jun 2006
    Posts
    9

    Having trouble with const

    I had to modify this code to inlcude a const. When I did that, I keep getting three errors.
    This is my code,
    1. what am I doing wrong?
    2. I'm suppose to have the empId left justified and the pay right justified. How do I do both of them?



    Code:
    #include "stdafx.h"
    #include <iostream>
    #include <iomanip>
    using namespace std;
    
    //Updating lass to calculate pay for an Employee.
    // Class definition.
    class Employee
    {
    private:
    	int			 _empId;			// Employee Id.
    	const double _payRate;		// Rate of Pay constant
    //	double	_hoursWorked;	// Hours Worked.
    
    public:
    	Employee( );			// Constructor.
    	Employee( int empId, double payRate );		// Overloaded Constructor.
    	double calculatePay( int hoursWorked );	// Calculates the Employees pay.
    	double salary;
    	void setEmpId( int empId );			// Mutator Method - allows you to set the employee id.
    	int  getEmpId( );					// Accessor Method - allows you to get the employee id. 
    	
    };
    
    // Constructor.
    Employee::Employee( )
    {
    	this->_empId = 1;
    	this->_payRate = 5.33;
    //	this->_hoursWorked = 10.0;
    }
    
    Employee::Employee( int empId  )
    {
    	this->_empId = empId;
    	
    }
    
    // Calculates the Employee's pay based upon the _payRate and _hoursWorked.
    double Employee::calculatePay( int hoursWorked )
    {
    	return this->_payRate * hoursWorked;
    }
    
    // Sets the Employee Id
    void Employee::setEmpId( int empId )
    {
    	this->_empId = empId;
    }
    
    // Gets the employee id.
    int Employee::getEmpId( )
    {
    	return this->_empId;
    }
    
    
    // Main C++ function.
    int _tmain(int argc, _TCHAR* argv[])
    {
    	const double _payRate = 3.75;
    	
    	Employee emp( 1, 12.50 );
    	double emp1Hours, emp2Hours, emp3Hours;
    	double salary = _payRate * emp1Hours;
    	cout << "Please enter number of hours worked: ";
    	cin >>  emp1Hours;
    	cout<< "setw(5)<<setiosflags(ios::left)<<setprecision(2)<<salary<<"; 
    	
    	cout<<"---------------------------------------------";
    
    	cout<< "Please type number of hours for second employee: ";
    	cin>> emp2Hours;
    	cout<< "setw(5)<<setiosflags(ios::left)<<setprecision(2)<<salary<<";
    
    	cout<<"---------------------------------------------";
    
    	cout<<"Please type third employee's hours worked: ";
    	cin>>emp3Hours;
    	cout<< "setw(5)<<setiosflags(ios::left)<<setprecision(2)<<salary<<";
    
    	cout<<"---------------------------------------------";
    
    	cout << "Employee " << emp.getEmpId( ) << "'s salary is : " << emp.calculatePay( 40 );
    
    	cout<<" Total is (emp1Hours + emp2Hours + emp3Hours)"<< endl;
    	
    	cout << endl << endl << "Please press a key and then press enter to quit." << endl;
    
    	
    	char a;
    	cin >> a;
    
    	return 0;
    }


    These are the errors:


    error C2758: 'Employee::_payRate' : must be initialized in constructor base/member initializer list

    error C2166: l-value specifies const object

    error C2511: 'Employee::Employee(int)' : overloaded member function not found in 'Employee'

  2. #2
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,045
    Code:
    Employee::Employee( int empId  )
    You don't have a prototype for this function in the class.

    error C2758: 'Employee::_payRate' : must be initialized in constructor base/member initializer list
    Since const values never change, you have to set them to something; in the case of class member variables, initialize them in a constructor initialization list.
    Code:
    Employee() : const_var(4) {}
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  3. #3
    Registered User
    Join Date
    Jan 2005
    Posts
    7,317
    You should almost always use the initalization list to initialize all of your member variables.

  4. #4
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Portugal
    Posts
    7,383
    When you declare a const data member you have to realize the difference between assignment and initialization. The way you built your constructors, they are assigning to _payRate. And yet a const value cannot be assigned. It should be initialized.

    In order for the const to be properly initialized you should include an initialization list when declaring the constructor.

    Code:
    Employee( int empId, double payRate ): _payRate(payRate);
    More problematic is your default constructor. As you can rapidly realize, you cannot change _payRate once it is properly initialized. So even if you provide that constructor with a default value, you have no way of changing it once the object is created.

    So... is _payRate really a constant? That is, is this a value that never gets changed once the object is created? If that is the only reason you declared it const, then drop the const specifier. You don't need it. All you have to do is to keep it private and not provide a setter function.

    EDIT: I also suggest you consider your default constructor. Do you need it. Some care must be given to this constructor. More often than not you will realize that a class is better off without one.
    Last edited by Mario F.; 06-19-2006 at 05:03 PM.
    The programmer’s wife tells him: “Run to the store and pick up a loaf of bread. If they have eggs, get a dozen.”
    The programmer comes home with 12 loaves of bread.


    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  5. #5
    Registered User
    Join Date
    Jan 2005
    Posts
    7,317
    >> If that is the only reason you declared it const, then drop the const specifier.
    No, leave the const there. It makes the code clearer and will help avoid programmer errors in the future. The only reason to remove the const would be if you wanted to allow the pay rate to change for a given instance of the class.

  6. #6
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Portugal
    Posts
    7,383
    Well true. Good advice.
    The programmer’s wife tells him: “Run to the store and pick up a loaf of bread. If they have eggs, get a dozen.”
    The programmer comes home with 12 loaves of bread.


    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  7. #7
    Registered User
    Join Date
    Jul 2003
    Posts
    450
    I would imagine different employees would have a different payrate.

  8. #8
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Portugal
    Posts
    7,383
    const doesn't preclude that. You are probably thinking static members. Const members still exist in every object of the class.
    The programmer’s wife tells him: “Run to the store and pick up a loaf of bread. If they have eggs, get a dozen.”
    The programmer comes home with 12 loaves of bread.


    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  9. #9
    Registered User
    Join Date
    Jul 2003
    Posts
    450
    Sorry you are correct I'm pretty rusty.

  10. #10
    Registered User
    Join Date
    Jun 2006
    Posts
    9
    Quote Originally Posted by dwks
    Code:
    Employee::Employee( int empId  )
    You don't have a prototype for this function in the class.


    Since const values never change, you have to set them to something; in the case of class member variables, initialize them in a constructor initialization list.
    Code:
    Employee() : const_var(4) {}
    Thanks for your assistance. I modified the constructors but i still get the same three errors. I also tried declaring the const variable before the emploee class line but that didn't change anything.

  11. #11
    Registered User
    Join Date
    Jun 2006
    Posts
    9
    Quote Originally Posted by Mario F.
    When you declare a const data member you have to realize the difference between assignment and initialization. The way you built your constructors, they are assigning to _payRate. And yet a const value cannot be assigned. It should be initialized.

    In order for the const to be properly initialized you should include an initialization list when declaring the constructor.

    Code:
    Employee( int empId, double payRate ): _payRate(payRate);
    More problematic is your default constructor. As you can rapidly realize, you cannot change _payRate once it is properly initialized. So even if you provide that constructor with a default value, you have no way of changing it once the object is created.

    So... is _payRate really a constant? That is, is this a value that never gets changed once the object is created? If that is the only reason you declared it const, then drop the const specifier. You don't need it. All you have to do is to keep it private and not provide a setter function.

    EDIT: I also suggest you consider your default constructor. Do you need it. Some care must be given to this constructor. More often than not you will realize that a class is better off without one.
    Thanks, I'll try to do the modifications as you specified.

  12. #12
    Registered User
    Join Date
    Jun 2006
    Posts
    9

    Update.

    I've made some progress and the class complies and calculates properly. I tried a few different things but I cannot get the cout statements to align empId to the left anf pay to the right. How do I do that?


    Code:
    #include "stdafx.h"
    #include <iostream>
    #include <iomanip>
    using namespace std;
    
    //Updating class to calculate pay for an Employee.
    // Class definition.
    
    const double _payRate = 3.75;
    
    class Employee
    {
    private:
    	int			 _empId;			// Employee Id.
    
    //	double	_hoursWorked;	// Hours Worked.
    
    public:
    	Employee( );			// Constructor.
    	Employee( int empId );		// Overloaded Constructor.
    	double calculatePay( int hoursWorked );	// Calculates the Employees pay.
    	double salary;
    	void setEmpId( int empId );			// Mutator Method - allows you to set the employee id.
    	int  getEmpId( );					// Accessor Method - allows you to get the employee id. 
    	
    };
    
    // Constructor.
    Employee::Employee()
    {
    	this->_empId = 1;
    	//this->_payRate = 5.33;
    	
    //	this->_hoursWorked = 10.0;
    }
    
    Employee::Employee( int empId  )
    {
    	this->_empId = empId;
    	//this->_payRate = payRate;
    	
    }
    
    // Calculates the Employee's pay based upon the _payRate and _hoursWorked.
    double Employee::calculatePay( int hoursWorked )
    {
    	return _payRate * hoursWorked;
    }
    
    // Sets the Employee Id
    void Employee::setEmpId( int empId )
    {
    	this->_empId = empId;
    }
    
    // Gets the employee id.
    int Employee::getEmpId( )
    {
    	return this->_empId;
    }
    
    
    // Main C++ function.
    int _tmain(int argc, _TCHAR* argv[])
    {
    	const double _payRate = 3.75;
    	
    	Employee emp( 1);
    	double emp1Hours, emp2Hours, emp3Hours;
    	double salary = _payRate * emp1Hours;
    	cout << "Please enter number of hours worked: ";
    	cin >>  emp1Hours;
    	cout<< "setw(5)<<setiosflags(ios::left)<<setprecision(2)<<salary<<"; 
    	
    	cout<<"---------------------------------------------";
    
    	cout<< "Please type number of hours for second employee: ";
    	cin>> emp2Hours;
    	cout<< "setw(5)<<setiosflags(ios::left)<<setprecision(2)<<salary<<";
    
    	cout<<"---------------------------------------------";
    
    	cout<<"Please type third employee's hours worked: ";
    	cin>>emp3Hours;
    	cout<< "setw(5)<<setiosflags(ios::left)<<setprecision(2)<<salary<<";
    
    	cout<<"---------------------------------------------";
    
    	cout<<" Total is (emp1Hours + emp2Hours + emp3Hours)"<< endl;
    	
    	cout << "Employee " << emp.getEmpId( ) << "'s salary is : " << emp.calculatePay( 40 );
    
    	cout << endl << endl << "Please press a key and then press enter to quit." << endl;
    
    	
    	char a;
    	cin >> a;
    
    	return 0;

  13. #13
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,045
    Code:
    cout<< "setw(5)<<setiosflags(ios::left)<<setprecision(2)<<salary<<";
    ->
    Code:
    cout<< setw(5)<<setiosflags(ios::left)<<setprecision(2)<<salary;
    setw() etc are functions. Don't put them in a string, otherwise "setw(5)..." will be printed. (I'm sure you found that out. )
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  14. #14
    Registered User
    Join Date
    Jun 2006
    Posts
    9
    Quote Originally Posted by dwks
    Code:
    cout<< "setw(5)<<setiosflags(ios::left)<<setprecision(2)<<salary<<";
    ->
    Code:
    cout<< setw(5)<<setiosflags(ios::left)<<setprecision(2)<<salary;
    setw() etc are functions. Don't put them in a string, otherwise "setw(5)..." will be printed. (I'm sure you found that out. )

    Thanks

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Function template has already been defined
    By Elysia in forum C++ Programming
    Replies: 19
    Last Post: 04-14-2009, 10:17 AM
  2. fatal error LNK1104
    By DMH in forum C++ Programming
    Replies: 2
    Last Post: 11-16-2005, 02:46 AM
  3. Memory leak - need help finding
    By ChadJohnson in forum C++ Programming
    Replies: 8
    Last Post: 04-06-2005, 07:26 PM
  4. Certain functions
    By Lurker in forum C++ Programming
    Replies: 3
    Last Post: 12-26-2003, 12:26 AM
  5. Color Variety
    By Unregistered in forum C++ Programming
    Replies: 7
    Last Post: 10-23-2002, 09:17 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21