Boost.Python - error with parametrized constructor - c++

I have got a toy class from tutorialspoint in a file test.h:
class Box {
public:
Box(int l, int b, int h)
{
length = l;
breadth = b;
height = h;
}
double getVolume(void) {
return length * breadth * height;
}
void setLength( double len ) {
length = len;
}
void setBreadth( double bre ) {
breadth = bre;
}
void setHeight( double hei ) {
height = hei;
}
private:
double length; // Length of a box
double breadth; // Breadth of a box
double height; // Height of a box
};
In the another file I have:
BOOST_PYTHON_MODULE(test)
{
namespace python = boost::python;
python::class_<Box>("Box")
.def("setLength", &Box::setLength )
.def("setBreadth", &Box::setBreadth)
.def("setHeight", &Box::setHeight )
.def("getVolume", &Box::getVolume );
}
When I compile this code I get the error message about the Box class constructor:
/usr/include/boost/python/object/value_holder.hpp:133:13: error: no matching function for call to ‘Box::Box()’
BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_UNFORWARD_LOCAL, nil)
^
What am I missing?
Do I need to write the constructor paramaters in BOOST_PYTHON_MODULE()? If so, how to do it?

You dont have a default constructor and you are missing the one you declared:
BOOST_PYTHON_MODULE(test) {
namespace python = boost::python;
python::class_<Box>("Box", boost::python::init<int, int, int>())
.def("setLength", &Box::setLength )
.def("setBreadth", &Box::setBreadth)
.def("setHeight", &Box::setHeight )
.def("getVolume", &Box::getVolume );
}

The compiler is complaining that Box doesn't provide a default constructor BOOST_PYTHON_MODULE needs:
no matching function for call to ‘Box::Box()
Simply define one:
class Box {
public:
Box() = default;
// [...]
};
Additionnaly, you can checkout mohabouje's answer.

Related

like to invoke parameter-ed constructor at declaration and definition or afterwards any how of an array-of-a-class

I have a following class and I am creating 1d array of that class. Class has two constructors. So when I create the array of class like 'Box b[5]',so the first constructor is getting called. What I like if there is a way I can initialize length,breadth,height at the time of declaration or definition or is there a way I can invoke the parameter-ed constructor of a class for same array object elements while/or after creating array b[x] (elements)?
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
class Box {
public:
// Constructor definition
Box ()
{
cout<<"without constructot"<<endl;
}
Box(double l, double b = 2.0, double h = 2.0) {
cout <<"Constructor called." << endl;
length = l;
breadth = b;
height = h;
}
double Volume() {
return length * breadth * height;
}
private:
double length; // Length of a box
double breadth; // Breadth of a box
double height; // Height of a box
};
int main()
{
Box b[5];
}

Sorting vector of objects with operator overloading in c++

I have one base class and I have 4 class derived.of course I write 2 class for example.
I created vector and fill it by objects of derived classes, then I want sort my vector base of area function. I want use operator overloading.
I define operator overloading but it not Completely!
please help me!
Thanks....
class Shape
{
public:
Shape() {}
virtual void draw() = 0;
virtual int area() = 0;
virtual void perimeter() = 0;
bool operator >(Shape * shape_one , Shape* shape_two )
{
return shape_one->area() > shape_two->area();
}
protected :
double height;
double width;
};
class Squar : public Shape
{
public:
Squar(int _width) {
width = _width;
}
void draw(){}
int area(){
return width * width;
}
void perimeter(){}
bool operator >(Squar * squar_one , Squar* squar_two )
{
return squar_one->area() > squar_two->area();
}
};
class Triangle : public Shape
{
public:
Triangle(int _width , int _height) {
width = _width;
height = _height;
}
void draw(){}
int area(){
return (width * height) / 2;
}
void perimeter(){}
bool operator >(Triangle * triangle_one , Triangle* triangle_two )
{
return triangle_one->area() > triangle_two->area();
}
};
int main()
{
Shape *rect = new Rectangular( 1 , 9);
Shape *squar = new Squar(5);
QVector <Shape *> list;
list.push_back(rect);
list.push_back(squar);
retuurn 0;
}
I understand answer the question.
add following code in base class :
bool operator <( Shape *item )
{
return this->area() < item->area();
}
and add following code in main :
std ::sort(list.begin() , list.end() ,[](Shape* ptr_l , Shape* ptr_r) { return *ptr_l < ptr_r;} );
This code is correct! :)

Class and construct Error C++

I need help with this error?
molecule.cpp:31:7: error: qualified reference to 'mole' is a constructor name rather than a type wherever a constructor can be declared
mole::mole(Atom1(), Atom2() ){
class mole {
private:
string name;
int proton;
int neutron;
int electron;
int valence;
public:
int mass();
mole();
mole(Atom, Atom);
mole(string);
mole(string,int,int,int);
};
mole::mole()
{
name="hydrogen";
proton=1;
neutron=0;
electron=1;
valence=1;
}
mole::mole(Atom1(), Atom2() ){
proton= Atom1.p + Atom2.p;
neutron=Atom1.n + Atom2.n;
electron=Atom1.e + Atom2.e;
}
In another file:
#include<iostream>
using namespace std;
class Atom {
private:
string name;
int proton;
int neutron;
int electron;
int valence;
public:
int mass();
Atom();
Atom(int,int,int);
Atom(string);
Atom(string,int,int,int);
};
Atom::Atom(){
name="hydrogen";
proton=1;
neutron=0;
electron=1;
valence=1;
}
Atom::Atom(int p, int n, int e){
proton=p;
neutron=n;
electron=e;
}
Atom::Atom(string n){
name=n;
}
Atom::Atom(string nm, int p, int n, int e){
name = nm;
proton=p;
neutron=n;
electron=e;
}
int Atom::mass(){
int mass = proton+neutron;
return mass;
}
I'm assuming that Atom is a class that is declared elsewhere? If you wanted to be able to accept two parameters of type Atom in the non-default constructor, you should declare it like so:
mole(Atom atom1, Atom atom2);
...
mole::mole(Atom atom1, Atom atom2) {
proton = atom1.p + atom2.p
....
}
So many errors. Let's tidy it up a bit and make it real C++.
mole::mole( const Atom & a, const Atom & b )
: proton( a.p + b.p )
, neutron( a.n + b.n )
, electron( a.e + b.e )
, valence{} // or whatever calculation you intended
{
}

How to sort an object array

I've created a class called Box that is pretty much what it sounds like. I want to sort these box objects, and I have created a function to do so.
void boxSort(Box array[], int size) {
Box temp;
bool swap;
do {
swap = false;
for(int count=0; count<(size-1); count++) {
int volume1 = array[count].getVolume(array[count].height, array[count].width, array[count].length);
int volume2 = array[count+1].getVolume(array[count+1].height, array[count+1].width, array[count+1].length);
if(volume1 > volume2) {
temp = array[count];
array[count] = array[count+1];
array[count+1] = temp;
swap = true;
}
}
}
while(swap);
}
This function sorts an array of objects of class Box.
Box class:
class Box {
public:
double height, width, length;
double getVolume(double, double, double);
double getSurfaceArea(double, double, double);
void setHeight(double);
void setWidth(double);
void setLength(double);
Box() {
height = width = length = 1;
}
Box(double h, double w, double l) {
setHeight(h);
setWidth(w);
setLength(l);
}
};
#endif
void Box::setHeight(double h) {
height = h;
}
void Box::setWidth(double w) {
width = w;
}
void Box::setLength(double l) {
length = l;
}
double Box::getVolume(double h, double w, double l) {
double volume = h*w*l;
return volume;
}
double Box::getSurfaceArea(double h, double w, double l) {
double surfaceArea = (h*w)*2 + (h*l)*2 + (l*w)*2;
return surfaceArea;
}
When I run this program I get an error:
linker command failed with exit code 1
This doesn't shown up on any particular line, and I have no idea what it means, so I'm a little lost on how to debug this.
The linker errors are reported if you have any problem with libraries or object files linked. Were you able to successfully build the executable?
I think this error is occurring due to more than one main() function in your code.You can have only one main() function.
Not sure about the error. But I would suggest changing boxSort function to something like this.
change getVolume to this
double Box::getVolume() {
return height*width*length;
}
and boxSort to this
void boxSort(std::array<Box, 3> boxes)
{
struct
{
bool operator()(Box x, Box y)
{
return x.getVolume() < y.getVolume();
}
}compFunc;
std::sort(boxes.begin(), boxes.end(), compFunc);
for(Box a: boxes)
{
std::cout<<a.getVolume()<<" ";
}
}
function call:
std::array<Box,3> boxes = {box1, box2, box3};
boxSort(boxes);

C++ class error message: no matching function for call

My program is supposed to calculate the surface area and volume of a box. I am to have the following functions: setHeight, setWidth, setLength, getVolume, getSurfaceArea.
When I compile my program I get the following error message:
boxMain.cpp: In function ‘int main()’:
boxMain.cpp:21: error: no matching function for call to 'Box::getVolume(double&, double&, double&)’
Box.hpp:20: note: candidates are: double Box::getVolume()
boxMain.cpp:23: error: no matching function for call to ‘Box::getSurfaceArea(double&, double&, double&)’
Box.hpp:21: note: candidates are: double Box::getSurfaceArea()
Based on my searches on this site, most answers seem to suggest that the default constructor doesn't exit or isn't working. I don't know if that is my issue as well, but I wrote the code for my default constructor according to textbook, so I have trouble figuring out what I did wrong.
The missing lines in my code below are just the descriptions and comments that I removed.
Any help would be appreciated! Thank you all so much in advance.
Here is my .hpp file:
#include <iostream>
#ifndef Box_HPP
#define BOX_HPP
class Box {
private:
double h, w, l;
double height, width, length;
public:
void setHeight(double h);
void setWidth(double w);
void setLength(double l);
double getVolume();
double getSurfaceArea();
Box();
};
Here is my function .cpp file:
#include <iostream>
#include <iomanip>
#include "Box.hpp"
double height;
double width;
double length;
Box::Box() {
height = 1.0;
width = 1.0;
length = 1.0;
}
void setHeight(double h) {
if(h < 0) {
std::cout << "Error. Height must be positive."
<< std::endl;
}
else {
height = h;
}
}
void setWidth(double w) {
if(w < 0) {
std:: cout << "Error. Width must be positive."
<< std::endl;
}
else {
width = w;
}
}
void setLength(double l) {
if(l < 0) {
std::cout << "Error. Length must be positive."
<< std::endl;
}
else {
length = l;
}
}
double getVolume() {
return (height * width * length);
}
double getSurfaceArea() {
return (2.0 * length * height + 2.0 * width * height);
}
Here is my main .cpp file:
#include <iostream>
#include <fstream>
#include "Box.hpp"
int main() {
Box box1;
double h, w, l;
std::cout << "Enter height" << std::endl;
std::cin >> h;
std::cout << "Enter width" << std::endl;
std::cin >> w;
std::cout << "Enter length" << std::endl;
std::cin >> l;
void setHeight(double h);
void setWidth (double w);
void setLength (double l);
std::cout << "volume: "
<< box1.getVolume(h, w, l) << std::endl;
std::cout << "surface: "
<< box1.getSurfaceArea(h, w, l) << std::endl;
return 0;
}
Box::getVolume is declared as taking no parameters, but in line 21 you call it with 3 arguments:
box1.getVolume(h, w, l)
Use simply box1.getVolume() instead. Similarly for Box::getSurface().
Also, use Box:: in front of all member function definitions, like void Box::setHeight(double h) {...}, otherwise you end up defining free standing functions and you'll get linker errors since the member functions end up not defined.
vsoftco's answer is mostly correct so I have up voted him, although I feel it would be good to add some more information to the answer to help explain it a bit better as well as help clean up several other issues you have here.
The error you had clearly explains the problem if you look at it. It mentions boxMain.cpp in the function int main() as having the problem. It further gives you the line number and mentions that there is "no matching function" for the "call" and in both instances notes the call as well as the possible candidates, which in this case is the methods without parameters.
with that aside here are some other tips that may help you avoid further frustration:
Prefer forward declarations instead of includes in your header files. In your case you don't need #include <iostream> at all in your box.hpp. The reason is that anything in your header is effectively leaked into any files that include your header. This is mainly to help reduce circular dependancies as well as shorten compile times when making changes. The Pimpl Idiom is an example pattern used with this mantra. I would not recommend using naked pointers, however, instead stick with RAII types such as smart pointers or plain references.
You either didn't paste all of your code or your include guard is wrong. You need a closing #endif in your header.
You should use a convention to name your member variables to avoid conflicts and keep your large .cpp files easier to read. This is a preference more then a rule but it helps. Something like _height, mHeight, _mHeight rather then height. Lower case camel style variable names are common for locals and parameters. It also looks like you really don't need the h,w,l members at all.
You should probably use assert for your error handling so as to optimize it out during release builds. That is of coarse unless you are intending to show the end user the error message. You may also consider using std::cerr instead.
The height, width, length variables in your .cpp are also extraneous and do not do what you think.
You should use an initialization list in your constructor instead of doing the simple work of assigning to variables in the body. There are several special situations as well but this can get you started.
ex: Box::Box() : height(1.0), width(1.0), length(1.0){}
The only method in the cpp you fully qualified with Box:: is the constructor. You need to do that with all the methods as well. ex: double Box::getVolume()
You are also not calling the correct methods in your main function (in fact you are not calling methods at all. You are basically forward declaring them.) you should be using an object to invoke the methods. This is why you didn't see a complaint in the error log about missing Box::
There is one major error in your header file that has nothing to do with your class's declaration, but has to do with the header during the pre-compilation stage. Your header guard is not correct as you have first have your #include <iostream> before the guard; this should be after the guard. Second your #ifndef CLASS_NAME does not match your #define CLASS_NAME and you are missing the matching #endif at the bottom of your header file. I will remove the #include <iostream> since it is not needed. The reason I am doing this is because if a user enters a value that is less than or equal to zero it will be set to a default value of 1. So there is no need to print out any error messages for this class.
Your class is close to what you need. There are a few things that would help to improve your class and maybe this will help.
Box.h
#ifndef BOX_H
#define BOX_H
class Box {
private:
double m_width;
double m_length;
double m_height;
double m_volume;
double m_surfaceArea;
public:
Box(); // Default Constructor
Box( double width, double length, double height );
// virtual ~Box(); // Default Okay
void setWidth( double width );
void setLength( double length );
void setHeight( double height );
double getWidth() const;
double getLegnth() const;
double getHeight() const;
double getVolume() const;
double getSurfaceArea() const;
private:
// If You Need Either The Copy Constructor Or The Assignment Operator
// Remove Them From The Private Section Into The Public Section
// Where You May Need To Implement Them Where The Default May Not Be Appropriate
Box( const Box& c ); // Not Implemented
Box& operator=( const Box& c ); // Not Implemented
void calculateVolume();
void calculateSurfaceArea();
}; // Box
#endif // BOX_H
Box.cpp
#include "Box.h"
// -------------------------------------------------------------------------
// Box() - Default Box Will Have a 1 x 1 x 1 Dimension
Box::Box() :
m_width( 1.0 ),
m_length( 1.0 ),
m_height( 1.0 ),
m_volume( 0.0 ),
m_surfaceArea( 0.0 ) {
calculateVolume();
calculateSuraceArea();
} // Box
// -------------------------------------------------------------------------
// Box() - User Defined Constructor
Box::Box( double width, double length, double height ) :
m_volume( 0.0 ),
m_surfaceArea( 0.0 ) {
if ( width <= 0 ) {
m_width = 1.0;
} else {
m_width = width;
}
if ( length <= 0 ) {
m_length = 1.0;
} else {
m_length = length;
}
if ( height <= 0 ) {
m_height = 1.0;
} else {
m_height = height;
}
calculateVolume();
calculateSurfaceArea();
} // Box
// -------------------------------------------------------------------------
// setWidth()
void Box::setWidth( double width ) {
// First Check To See If Value Passed In Is Same Member Value
if ( width == m_width ) {
// Nothing To Do
return;
} else if ( width <= 0 ) {
m_width = 1.0
} else {
m_width = width;
}
calculateVolume();
calculateSurfaceArea();
} // setWidth
// -------------------------------------------------------------------------
// setLength()
void Box::setLength( double length ) {
// First Check To See If Value Passed In Is Same Member Value
if ( length == m_length ) {
// Nothing To Do
return;
} else if ( length <= 0 ) {
m_length = 1.0
} else {
m_length = length;
}
calculateVolume();
calculateSurfaceArea();
} // setLength
// -------------------------------------------------------------------------
// setHeight()
void Box::setHeight( double height ) {
// First Check To See If Value Passed In Is Same Member Value
if ( height == m_height ) {
// Nothing To Do
return;
} else if ( height <= 0 ) {
m_height = 1.0
} else {
m_height = height;
}
calculateVolume();
calculateSurfaceArea();
} // setHeight
// -------------------------------------------------------------------------
// getWidth()
double Box::getWidth() const {
return m_width;
} // getWidth
// -------------------------------------------------------------------------
// getLength()
double Box::getLength() const {
return m_length;
} // getLength
// -------------------------------------------------------------------------
// getHeight()
double Box::getHeight() const {
return m_height;
} // getHeight;
// -------------------------------------------------------------------------
// getVolume()
double Box::getVolume() const {
return m_volume;
} // getVolume
// -------------------------------------------------------------------------
// getSurfaceArea()
double Box::getSurfaceArea() const {
return m_surfaceArea;
} // getSurfaceArea
// -------------------------------------------------------------------------
// calculateVolume()
void Box::calculateVolume() {
m_volume = m_width * m_length * m_height;
} // calculateVolume
// -------------------------------------------------------------------------
// calculateSurfaceArea()
void Box::calculateSurfaceArea {
m_dSurfaceArea = (m_width * m_length * 2) +
(m_width * m_height * 2) +
(m_length * m_height * 2);
} // calculateSurfaceArea
With the design of this class the calculations for both the volume and surface area are private to this class only for all they do is an internal calculation that get saves into the classes member variable where there are public access methods available to retrieve them. Also each of the 3 dimensional setters does the same check as both constructors for values that are less than and equal to 0 and if so will default them to 1.
If the value that is passed into any of the setter functions is the same that is already stored the function will do nothing and just return. If the value is greater than 0 and is not equal to what is already saved, it will overwrite the member variable and call both of the private calculate methods to update the volume and surface area.
Now if you want to improve this for better performance then you can declare both calculate methods as inline, move them out of the cpp file and either add them into the header file after your class declaration and before the #endif or you can add an `#include "Box.inl" and just create another header file type with the same name as the class except with the inl extension and cut and paste these two functions in there.