Search code examples
c++classconstructorheaderc-strings

No matching Constructor Error For Initialization in c++. Whats wrong with my constructor?


I have a class in a header file as follows:

#include <iostream>
#include <string>
#include <sstream>
using namespace std;
    class ShowTicket {
    public:
        bool is_sold(void){
            if (sold_status == true){
                return true;
            }
            else{
                return false;
            }
        }
        void sell_seat(void){
            sold_status = true;
        }
        string print_ticket(void){
            ostringstream sout;
            if(sold_status == true){
                sout<<row<<" "<<seat_number<<"sold";
            }
            else{
                sout<<row<<" "<<seat_number<<"available";
            }
            return sout.str();
        }
        bool sold_status;
        const char* row;
        const char* seat_number;

        ShowTicket(const char* Row, const char* SeatNumber):
        sold_status{false},
        row(Row),
        seat_number(SeatNumber)
        {}
    };


The main function to test this class is as follows:

#include <iostream>
#include <string>
#include <sstream>
#include "showticket.h"
using namespace std;

int main () {
    ShowTicket myticket1("AA","101");
    ShowTicket myticket2("AA","102");
  if(!myticket1.is_sold())
    myticket1.sell_seat ();
  cout << myticket1.print_ticket() << endl;
  cout << myticket2.print_ticket() << endl;
  return 0;
}



When myticket 1 and 2 are created there is an error "No matching constructor for initialization of 'ShowTicket" but I believe my constructor accepts these parameters so I'm not sure how to resolve.

Any advice would be appreciated.


Solution

  • By the looks of it, you only want to supply two arguments, but your constructor requires three:

    ShowTicket(const char* row, const char* seat_number, bool sold_status){
        sold_status = false;
    }
    

    The body of the constructor makes be believe that you want to initialize a newly created ShowTicket with sold_status set to false. You can do that directly in the member initializer list:

    ShowTicket(const char* row, const char* seat_number) : // note the colon
        sold_status{false} // <- here
    {}
    

    If that's not the case, you can make sold_status have a default value, below it's set to false:

    ShowTicket(const char* row, const char* seat_number, bool sold_status = false) :
        sold_status{sold_status} 
    {}
    

    I also recommend using different names for the arguments and the member variables. It can easily get messy otherwise:

    ShowTicket(const char* row, const char* seat_number, bool SoldStatus = false) :
        sold_status{SoldStatus} 
    {}
    

    Also note that you don't actually allocate memory for and save the row and seat_number in the constructor. Calling your print_ticket function will therefore cause undefined behavior. I recommend that you replace the raw pointers and replace them with std::strings:

            std::string row;
            std::string seat_number;
    

    You can now save all in the constructor and not have to worry about memory management:

    ShowTicket(const char* Row, const char* SeatNumber, bool SoldStatus = false) :
        sold_status{SoldStatus},
        row(Row),
        seat_number(SeatNumber)
    {}
    

    You may also want to consider taking the row and seat_number arguments as const std::string&s or std::string_views (since C++17) to make it easier to work with in general.