I Have a problem with creating a copyconstructor for my doublependulum class. I Created one in my doubelpendulum.h file, but it doesn’t seem to recognize it in doublependulum.cpp. I keep getting this error :
error C2512: ‘Pendulum’ : no appropriate default constructor available
I don’t understand why I have to add an appropriate constructor or why the one I defined ( rule 103-104) is not correct. If so, could anyone please tell me why it is neccessarry or what is wrong with mine?
pendulum.h
#include<string>
using std::string;
#ifndef pendulum_H
#define pendulum_H
class Pendulum
{
public:
Pendulum(const double,const double,double,double);
//check function
const double check(const double, const string) const; //used for (L,M)
// getfuncties
double getL() const;
double getM() const;
double getTheta();
double getOmega();
//overload operator
Pendulum operator+ (Pendulum);
Pendulum operator*(const double a);
Pendulum operator=(Pendulum);
//copy constructor
Pendulum(const Pendulum& );
private:
double L_,M_,Theta_,Omega_;
};
#endif
pendulum.cpp
#include "pendulum.h"
#include <iostream>
#include <string>
using namespace::std;
//constructor
Pendulum::Pendulum(const double L, const double M, double Theta, double Omega)
:L_(check(L,"L")),M_(check(M,"M"))
{}
//check functie
const double Pendulum::check(const double d, const string str) const
{
if (d<0.)
{
cout << "ERROR: " << str << " (" << d << ") has to be positive" << endl;
exit(EXIT_FAILURE);
}
return d;
}
//getfuncties
double Pendulum::getM() const
{
return M_;
}
double Pendulum::getL() const
{
return L_;
}
double Pendulum::getTheta()
{
return Theta_;
}
double Pendulum::getOmega()
{
return Omega_;
}
//overloading operators
Pendulum Pendulum::operator+ (Pendulum param)
{
return Pendulum(L_, M_, Theta_+param.Theta_, Omega_+param.Omega_);
}
Pendulum Pendulum:: operator* (const double param)
{
return Pendulum(L_, M_, param*Theta_, param*Omega_);
}
Pendulum Pendulum::operator=(Pendulum param)
{
return Pendulum(L_, M_, param.Theta_, param.Omega_);
}
//copy constructor
Pendulum::Pendulum(const Pendulum& Object)
{
*this=Object;
}
doublependulum.h
#ifndef doublependulum_H
#define doublependulum_H
#include "pendulum.h"
class DoublePendulum
{
public:
//constructor
DoublePendulum(Pendulum ,Pendulum );
//getfuncties
Pendulum getUp();
Pendulum getDown();
//Overload operators
DoublePendulum operator+ (DoublePendulum);
DoublePendulum operator*(const double a);
DoublePendulum &operator=(const DoublePendulum &);
//copy constructor
DoublePendulum(const DoublePendulum& );
private:
Pendulum PendUp;
Pendulum PendDown;
};
#endif
doublependulum.cpp
#include "doublependulum.h"
//constructor
DoublePendulum::DoublePendulum(Pendulum Up,Pendulum Down)
:PendUp(Up),PendDown(Down)
{}
//getfunctions
Pendulum DoublePendulum::getUp()
{
return PendUp;
}
Pendulum DoublePendulum::getDown()
{
return PendDown;
}
//Overload operators
DoublePendulum DoublePendulum::operator+ (DoublePendulum param)
{
return DoublePendulum(PendUp + param.PendUp,PendDown + param.PendDown);
}
DoublePendulum DoublePendulum::operator* (const double param)
{
return DoublePendulum(PendUp*param,PendDown*param);
}
DoublePendulum& DoublePendulum::operator= (const DoublePendulum& param)
{
return *this; // assign to members of this object
}
//Copy constructor
DoublePendulum::DoublePendulum(const DoublePendulum& Object)
{
*this=Object;
}
Main.cpp
#include "pendulum.h"
#include "doublependulum.h"
int main()
{return 0;}
Everything compiles until I add rules : 143-147
I get this error:
error C2512: 'Pendulum' : no appropriate default constructor available
error C2512: 'Pendulum' : no appropriate default constructor available
And a worrisome warning
Generating Code…
c:\users\niels\documents\visual studio 2010\projects\examenopdracht\examenopdracht\pendulum.cpp(55): warning C4717: ‘Pendulum::Pendulum’ : recursive on all control paths, function will cause runtime stack overflow
I’ve been searching for hours and hours and hope someone can explain to me what is wrong with my constructor.
The first problem is that you are attempting to default-construct members
PendUpandPendDownof typePendulumin your classDoublePendulum, while your classPendulumhas no default constructor. You can’s default-construct a class that has no default constructor. Either provide a default-constructor for classPendulumor stop trying to default-construct it inDoublePendulum. Which is the proper solution depends on your intent. Only you know what your intent was.As it has been noted in other answers, the reason your class
Pendulumhas no default constructor is that in C++ once you provide any user-defined constructor for the class, the compiler immediately stops providing the implicit default constructor for that class. In your case you explicitly declared two constructors in classPendulum, which automatically disabled its default constructor. To re-enable it you have to declare it explicitly.The second problem is rooted in the design of copy-constructor and copy-assignment operator in class
Pendulum. You implemented the copy-constructor as a simple call to the copy-assignment operator. However, your copy-assignment operator accepts its parameter by value. This means that in order to prepare the parameter the actual argument has to be copy-constructed by a call to copy-constructor. This is your infinite recursion. I.e. in order to complete the copy-constructor you have to call the copy-assignment, but in order to call the copy-assignment you have to call the copy-constructor.Firstly, why have you made your copy-assignment in class
Pendulumto accept its argument by value? In fact, the current implementation of copy-assignment operator doesn’t seem to make any sense at all: it doesn’t assign anything to its left-hand side. Make your copy-assignment accept its argument by const reference and the infinite recursion problem should go away. Also, make your copy-assignment to actually assign things to its left-hand side (i.e. the*thisobject).Secondly, the very idea of implementing the copy-constructor through a call to copy-assignment operator is broken. Assignment expects an object in a fully-constructed state, while inside the constructor the object is not constructed yet. A better idea would be to do it the other way around: to implement the copy-assignment through copy-construction by using the well-known copy-and-swap idiom.