Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ error: no matching constructor for initialization of

Im practicing memberwise assignment in C++, where you can set the values of one object to another object of the same class. The idea of the program is to initialize a rectangle object with some values and create another rectangle object but assign the value of the first into the second.

Its giving me an error, which is posted below, and I can't figure out what it is and its driving me nuts lol

This is my Rectangle.h

#ifndef RECTANGLE_H
#define RECTANGLE_H

class Rectangle {
    private:
        double length;
        double width;
    public:
        Rectangle(double, double);
        double getLength() const;
        double getWidth() const;
};

Rectangle::Rectangle(double l, double w) {
    length = l;
    width = w;
}

double Rectangle::getWidth() const { return width; }
double Rectangle::getLength() const { return length; }

#endif

This is my Rectangle.cpp

#include <iostream>
#include "rectangle.h"
using namespace std;

int main()
{
    Rectangle box1(10.0, 10.0);
    Rectangle box2;

    cout << "box1's width and length: " << box1.getWidth() << ", " << box1.getLength() << endl;
    cout << "box2's width and length: " << box2.getWidth() << ", " << box2.getLength() << endl;

    box2 = box1;

    cout << "box1's width and length: " << box1.getWidth() << ", " << box1.getLength() << endl;
    cout << "box2's width and length: " << box2.getWidth() << ", " << box2.getLength() << endl;

    return 0;
}

This is the error when I compile.

skipper~/Desktop/Programming/Memberwise: g++ rectangle.cpp 
rectangle.cpp:7:12: error: no matching constructor for initialization of
      'Rectangle'
        Rectangle box1(10.0, 10.0);
                  ^    ~~~~~~~~~~
./rectangle.h:4:7: note: candidate constructor (the implicit copy constructor)
      not viable: requires 1 argument, but 2 were provided
class Rectangle {
  ^
./rectangle.h:4:7: note: candidate constructor
      (the implicit default constructor) not viable: requires 0 arguments, but 2
      were provided
1 error generated.

EDIT: This is how I was able to make it work. I moved everything into rectangle.cpp and gave the constructor default arguments.

EDITED rectangle.cpp

#include <iostream>
using namespace std;

class Rectangle {
     private:
         double length;
         double width;
    public:
        //Rectangle();
        Rectangle(double = 0.0, double = 0.0);
        double getLength() const;
        double getWidth() const;
 };

 int main()
 {
    Rectangle box1(10.0, 10.0);
    Rectangle box2;

    cout << "box1's width and length: " << box1.getWidth() << ", " << box1.getLength() << endl;
    cout << "box2's width and length: " << box2.getWidth() << ", " << box2.getLength() << endl;

    box2 = box1;

    cout << "box1's width and length: " << box1.getWidth() << ", " << box1.getLength() << endl;
    cout << "box2's width and length: " << box2.getWidth() << ", " << box2.getLength() << endl;

    return 0;
}

Rectangle::Rectangle(double l, double w) {
    length = l;
    width = w;
}

double Rectangle::getWidth() const { return width; }
double Rectangle::getLength() const { return length; }

The only changes I made were giving default arguments to my user-defined constructor. However, it wasn't able to work when the changes were in rectangle.h. However, when I moved the class and member function definitions to rectangle.cpp it was able to work. So, I got the program to work but I didn't address the real issue, which is when the class and member function definitions are in rectangle.h, it won't compile.

If anyone has faced this problem and has found a solution to this, please let me know how you did it. Thanks :)

like image 604
skipper Avatar asked May 16 '15 04:05

skipper


2 Answers

In the line

Rectangle box2; // no default constructor, error

you are trying to invoke the default constructor of Rectangle. The compiler does not generate such a default constructor anymore, because your Rectangle has a user defined constructor that takes 2 parameters. Therefore, you need to specify the parameters, like

Rectangle box2(0,10);

The error I get when compiling your code is:

Rectangle.cpp:8:15: error: no matching function for call to 'Rectangle::Rectangle()' Rectangle box2;

A solution is to create a default constructor for Rectangle, since it is not automatically generated anymore due to your user defined one:

Rectangle(); // in Rectangle.h

Rectangle::Rectangle(){} // in Rectangle.cpp (or Rectangle::Rectangle() = default; in C++11)

Another solution (and the preferable one, since it doesn't leave the data un-initialized) is to assign default arguments to your existing constructor.

Rectangle::Rectangle(double l = 0, double w = 0); // only in Rectangle.h

In this way, you make your class Default-Constructible.

like image 80
vsoftco Avatar answered Sep 28 '22 12:09

vsoftco


A compiler generated default constructor is only generated if you have no defined constructors. You define a constructor, so if you want a default constructor you have to provide it yourself. Probably the easiest (arguably) is to provide it by using default arguments in your two argument constructor:

Rectangle(double l=0, double w=0)

Also you should use the inline keyword as shown below or you may find you get linker errors:

inline Rectangle::Rectangle(double l, double w) {
    length = l;
    width = w;
}

inline double Rectangle::getWidth() const { return width; }
inline double Rectangle::getLength() const { return length; }
like image 37
Steve Avatar answered Sep 28 '22 10:09

Steve