2015-05-16 4 views
2

Im практикует назначение по частям в C++, где вы можете установить значения одного объекта другому объекту того же класса. Идея программы состоит в том, чтобы инициализировать объект прямоугольника с некоторыми значениями и создать другой объект прямоугольника, но назначить значение первого во второе.Ошибка C++: никакой конструктор соответствия для инициализации

Его дает мне ошибку, которая размещена ниже, и я не могу понять, что это и его сводит меня с ума лол

Это мой 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 

Это мой 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; 
} 

Это ошибка при компиляции.

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: Так я смог заставить его работать. Я переместил все в rectangle.cpp и дал аргументы по умолчанию для конструктора.

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; } 

Единственные изменения, которые я сделал, были давать аргументы по умолчанию для моего пользовательского конструктора. Однако он не смог работать, когда изменения были в rectangle.h. Однако, когда я переместил определения функции класса и члена в файл rectangle.cpp, он смог работать. Итак, я получил программу для работы, но я не рассматривал реальную проблему, то есть когда определения функции класса и члена находятся в rectangle.h, она не будет компилироваться.

Если кто-то столкнулся с этой проблемой и нашел решение этого вопроса, сообщите мне, как вы это сделали. Спасибо :)

ответ

2

В строке

Rectangle box2; // no default constructor, error 

вы пытаетесь вызвать конструктор по умолчанию Rectangle. Компилятор больше не создает такой конструктор по умолчанию, потому что ваш Rectangle имеет определяемый пользователем конструктор, который принимает 2 параметра. Таким образом, вам необходимо указать параметры, как

Rectangle box2(0,10); 

Я получаю ошибку при компиляции кода является:

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

Решение состоит в том, чтобы создать конструктор по умолчанию для Rectangle, так как она не автоматически генерируется больше из-за вашего пользователя определяется один:

Rectangle(); // in Rectangle.h 

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

Другое решение (и предпочтительный один, так как она не выходит из данных ООН инициализирован) является как знаменуйте аргументы по умолчанию для вашего существующего конструктора.

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

Таким образом, вы создаете свой класс Default-Constructible.

+0

Так что, насколько я понимаю, всякий раз, когда я создаю определяемый пользователем конструктор, я должен также создать конструктор по умолчанию. Это всегда было на C++? – skipper

+0

@ skipper Да. Однако ваш конструктор, определенный пользователем, также может быть конструктором по умолчанию, если вы предоставляете аргументы по умолчанию, поэтому нет необходимости предоставлять 2 разных конструктора. Конструктор по умолчанию - это любой конструктор, который позволяет вызывать без аргументов. Для более подробной информации смотрите [здесь] (http://en.cppreference.com/w/cpp/language/default_constructor). – vsoftco

0

Созданный компилятором конструктор по умолчанию генерируется только в том случае, если у вас нет определенных конструкторов. Вы определяете конструктор, поэтому, если вы хотите использовать конструктор по умолчанию, вы должны предоставить его самостоятельно.Наверное, самый простой (возможно), чтобы обеспечить его с помощью аргументов по умолчанию в вашем два аргумента конструктора:

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

Также вы должны использовать inline ключевое слово, как показано ниже, или вы можете обнаружить, вы получите ошибки компоновщика:

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; } 
+0

Должен ли конструктор по умолчанию не иметь аргументов? – skipper

+0

@skipper: конструктор по умолчанию должен вызываться без аргументов. Все параметры по умолчанию удовлетворяют этому. – Steve

+0

Мне не удалось заставить его работать, добавив аргументы по умолчанию в rectangle.h. Однако я переместил определения функции класса и члена в файл rectangle.cpp, и он отлично работал с использованием аргументов по умолчанию. Таким образом, это решение, но не очень удовлетворительное, потому что я мог столкнуться с той же проблемой в будущем и не иметь решения для этого. – skipper

Смежные вопросы