简体   繁体   中英

confused about C++ compiler error

I'm totally confused. I posted this code in another forum (cplusplus) earlier and got help but I don't understand why the compiler gave me this error and when I asked about that there there was no response so I am hoping someone could explain it in a more detail here.

This is the error:

person.cpp: In constructor 'Person::Person(QString)': person.cpp:12:16: error: no matching function for call to 'Position::Position()' : m_Name(name)

As you can see from the code posted below the line pointed to in the error - person.cpp:12:16 - is not "'Position::Position()' : m_Name(name).

This is the suggested solutions (#2 worked):

You didn't specify what constructor should be used to construct m_Position so the compiler assumes you want to use the default constructor (the constructor that takes no arguments). The problem is that Position doesn't have a default constructor so that is why you get the error.

There are two ways you can solve this.

  1. Add a default to Position.
  2. Specify in the Person constructor that you want to use an existing constructor to construct m_Position.

Person::Person(QString name) : m_Name(name), m_Position("123", "abc") {

}

This is where I'm still confused about why the compiler would be pointing to that line in that file with that error; I guess, why it would require that constructor at that point? I'm assuming it kind of got to that point then stopped and read down the file until it saw the reference to Position and Employer in setPosition() then balked and printed the error.

But if that's the case then I still don't see why it would need that particular constructor and not either of the other two I tried (default with no args and cstor with one arg). When you (other forum) point out

"specify what constructor should be used to construct m_Position"

I thought I had read somewhere that the compiler would create a default copy constructor on the fly and that is what I was expecting would happen in setPosition() (where Position and Employer are referenced) as, for now, I'm just trying to get the mechanics of this to function then I would flesh out the little details later.

So that's my question: Why did the compiler do that?

Here's the original code (more or less).

person.cpp ===========================================

// Person.cpp
// pn Mar03-2014

#include <QString>
#include <QTextStream>
//#include "position.h"
#include "person.h"
//#include "employer.h"

Person::Person(QString name)
  : m_Name(name)
{
}

QString Person::toString()
{
  QString buffer;
  QTextStream bufStr(&buffer);
  bufStr << "Person Name: " << m_Name << endl;
  //buffer = "Person Name: " + m_Name + "\n";
  return buffer;
}

void Person::setPosition(Employer newC, Position newP)
{
  m_Position = newP;
  m_Employer = newC;
}

person.h =============================================

#ifndef _PERSON_H_ 
#define _PERSON_H_  

#include <QString>
#include "employer.h"
#include "position.h"

//class Employer;
//class Position;

class Person
{

  public:

    Person(QString name);
    void setPosition(Employer newC, Position newP);
    QString toString();

  private:

    QString m_Name;
    bool m_Employed;
    Position m_Position;
    Employer m_Employer;

};

#endif

position.h ===========================================

#ifndef _POSITION_H_ 
#define _POSITION_H_  

#include <QString>

//class Employer;
//class Person;

class Position
{

  public:

    Position(QString name, QString description);
    QString toString();

  private:

    QString m_Name;
    QString m_Description;

};

#endif

position.cpp =========================================

// Position.cpp
// pn Mar03-2014

#include <QString>
#include <QTextStream>
#include "position.h"
//#include "person.h"
//#include "employer.h"

Position::Position(QString name, QString description)
  : m_Name(name), m_Description(description)
{

}

QString Position::toString()
{
  QString buffer;
  QTextStream bufStr(&buffer);
  bufStr << "Position Name: " << m_Name << endl;
  bufStr << "Position Description: " << m_Description << endl;
  //buffer = "Position Name: " + m_Name + "\n";
  //return buffer.toStdString();
  return buffer;
}

employer.h ===========================================

// employer.h
// pn mar08-2014

#ifndef _EMPLOYER_H_ 
#define _EMPLOYER_H_  

#include <QString>
//using namespace std;

//class Person;
//class Position;


class Employer
{

  public:

    Employer(QString name, QString market);
    // bool hire(Person& newHire, Position pos);
    QString toString();

  private:

    QString m_Name;
    QString m_Market;

};

#endif

employer.cpp ==========================================

// employer.cpp
// pn Mar05-2014

#include <QString>
#include <QTextStream>
#include "position.h"
#include "person.h"
#include "employer.h"

Employer::Employer(QString name, QString market)
  : m_Name(name), m_Market(market) {}

QString Employer::toString()
{
  QString buffer;
  QTextStream bufStr(&buffer);
  bufStr << "Employer Name: " << m_Name << endl;
  bufStr << "Employer Market: " << m_Market << endl;
  //buffer = "Person Name: " + m_Name + "\n";
  //return buffer.toStdString();
  return buffer;  //QString
}

/*
bool Employer::hire(Person& newHire, Position pos)
{
  return true; 
}
*/

work.cpp (main) ======================================

// work.cpp
// pn mar05-2014

#include <QString>
#include <QTextStream>
#include <iostream>
#include "person.h"
#include "employer.h"
#include "position.h"

using namespace std;

int main()
{

  QString name;
  QString company;
  QString location;
  Person phil("Bozo");
  Employer sst("SST", "Speed");
  Position posture("Standing", "Not Sitting");
  //QTextStream qts();
  //qts << phil.toString();
  name = phil.toString();
  cout << name.toStdString();
  company = sst.toString();
  cout << company.toStdString();
  location = posture.toString();
  cout << location.toStdString();

  return 0;

}

rest of errors =======================================

person.cpp:12:16: note: candidates are:
In file included from person.h:6:0,
                 from person.cpp:7:
position.h:14:5: note: Position::Position(QString, QString)
     Position(QString name, QString description);
     ^
position.h:14:5: note:   candidate expects 2 arguments, 0 provided
position.h:9:7: note: Position::Position(const Position&)
 class Position
       ^
position.h:9:7: note:   candidate expects 1 argument, 0 provided
person.cpp:12:16: error: no matching function for call to ‘Employer::Employer()’
   : m_Name(name)
                ^
person.cpp:12:16: note: candidates are:
In file included from person.h:5:0,
                 from person.cpp:7:
employer.h:19:5: note: Employer::Employer(QString, QString)
     Employer(QString name, QString market);
     ^
employer.h:19:5: note:   candidate expects 2 arguments, 0 provided
employer.h:14:7: note: Employer::Employer(const Employer&)
 class Employer
       ^
employer.h:14:7: note:   candidate expects 1 argument, 0 provided
make: *** [person.o] Error 1

======================================================

Your class Person includes data member m_Position of type Position

class Person
{

  public:

  //...
  private:

    Position m_Position;
    //...
};

Class Position has no default constructor because there is explicitly declared constructor with parameters

class Position
{

  public:

    Position(QString name, QString description);
    //...
};

When you create an object of type Person then its constructor

Person::Person(QString name)
  : m_Name(name)
{
}

is called. As you did not initialized its data member m_Position in mem-initializer list ( you only initialized data member m_Name) then the constructor tries to initialize it itself calling the default constructor of class Position. However as I pointed out above class Position has no default constructor and the compiler issues the error.

You could defined the constructor of class Person for example the following way

Person::Person(QString name)
  : m_Name(name), m_Position( "", "" )
{
}

Or instead of empty strings you could pass something else to initialize m_Person.

the short answer: You have a circular dependancy. And your trying to convert a string into a QString.

The long answer: The employer.cpp #including the person, yet the person.h is #including the employer. There should never be circular dependancies.

Here is a picture to illustrate: http://i.stack.imgur.com/AdZ8i.jpg

Also, you are attempting to convert a string (or c-string) into a QString. Try creating a helper function to ease with the conversions (if one hasn't been created yet).

And lastly, you need to initialize ALL of your member variables.

Person::Person(QString name)
: m_Name(name),
m_Employed(false),
m_Position(Position(QString(), QString())),
m_Employer(Employer(QString(), QString()))
{
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM