Hello I am a student learning c++ and I am just starting to learn OOP. The problem is in my MAIN however I am showing all of my files in case it is from another file.
I have written my hpp and cpp file and now I am just working on my main for testing. The class is called Box and when I create an object box1 or box 2 and attempt to access my functions it says there are two few arguments. It says this regardless of whether I put box1.calcVolume(double h, double w, double l) or box1.calcVolume();
So the issue is on the line(s) that say:
double volume2 = box2.calcVolume();
double volume1 = box1.calcVolume();
double surfaceArea1 = box1.calcSurfaceArea();
If anyone can spot something that I missing our may not understand please let me know.
This is the header file:
#pragma once
#include <iostream>
#ifndef BOX_HPP
#define BOX_HPP
class Box
{
private:
double height;
double width;
double length;
public:
void setHeight(double h);
void setWidth(double w);
void setLength(double l);
double calcVolume(double h, double w, double l);
double calcSurfaceArea(double h, double w, double l);
Box();
Box(double height, double width, double length);
};
#endif
This is the CPP file
#include <iostream>
#include "Box.hpp"
Box::Box()
{
setHeight(1);
setWidth(1);
setLength(1);
}
Box::Box(double h, double w, double l)
{
setHeight(h);
setWidth(w);
setLength(l);
}
void Box::setHeight(double h)
{
height = h;
}
void Box::setWidth(double w)
{
width = w;
}
void Box::setLength(double l)
{
length = l;
}
double Box::calcVolume(double h, double w, double l)
{
double volume;
volume = h * w * l;
return volume;
}
double Box::calcSurfaceArea(double h, double w, double l)
{
double surfaceArea;
surfaceArea = 2 * (h*w) + 2 * (h*l) + 2 * (l*w);
return surfaceArea;
}
my BoxMain file:
#include <iostream>
#include "Box.hpp"
using std::cout;
using std::cin;
using std::endl;
int main()
{
Box box1(1.1, 2.4, 3.8);
Box box2;
box2.setHeight(12);
box2.setWidth(22.3);
box2.setLength(2.3);
double volume2 = box2.calcVolume();
double volume1 = box1.calcVolume();
double surfaceArea1 = box1.calcSurfaceArea();
cout << box1.calcVolume(); << endl; //testing different methods
return 0;
}
Your method takes three parameters:
double Box::calcVolume(double h, double w, double l)
{
double volume;
volume = h * w * l;
return volume;
}
So, you would call it like so:
Box b;
double volume = b.calcVolume(1, 2, 3);
But that's not quite right. An instance of Box knows how big it is, because you pass a size to the constructor, which stores the sizes in the fields width, height, and length. You probably want something like this:
double Box::calcVolume()
{
volume = height * width * length;
return volume;
}
You have the code wrong. The dimensions of the box are known during the creation of box object. The length, width and height are already available - updated in the member variables.
Functions calcVolume and calcSurfaceArea should not take arguments but return the computed value. Modified code below:
double Box::calcVolume()
{
return height*width*length;
}
double Box::calcSurfaceArea()
{
return 2*((height*width) + (height*length) + (length*width));
}
Also, remember to modify the .hpp file with the declarations corresponding to the code above.
Declaration in the .hpp file should be
double calcVolume();
double calcSurfaceArea();
I have solved the problem. I removed the arguments in calcVolume and calcSurfaceArea everywhere in my code and it resolved the error.
Related
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);
Both base classes, Arc and Lines, are derived from class Shape.
The compiler says Ojbect b1 "error: shape is ambiguous". I know that two instances of Shape are being created, but don't know how to resolve it?
Graph_lib::Box b1(Point,100,100), 100,100);
win1.attach(b1);
This class will be able to draw a box with rounded corners. I just wrote the code for the Box Lines part, I didn't get to the Arc yet since this won't even work.
//------------------------------------------------------------------------------
struct Box : Lines , Arc {
Box(Point xy, int ww, int hh);
void Top_segment();
void Bottom_segment();
void Left_side_segment();
void Right_side_segment();
void draw_lines() const;
int height() const { return h; }
int width() const { return w; }
private:
int h; // height
int w; // width
double width_tenth; //10% of the width that will calculate the length to remove from each side to make room for the arcs
};
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
Box::Box(Point xy, int ww, int hh): w(ww), h(hh)
{
width_tenth = (xy.x + w) * 0.10;
if (h<=0 || w<=0) error("Bad box: non-positive side");
}
//------------------------------------------------------------------------------
void Box::Top_segment()
{
double top_seg_begin_w; //where the line segment will begin after deducting 10% of w;
double top_seg_end_w; //where the line segment will end after deducting 10% of w;
top_seg_begin_w = xy.x + width_tenth;
top_seg_end_w = (xy.x + w) - width_tenth;
Lines::add(Point(top_seg_begin_w,xy.y),Point(top_seg_end_w,xy.y));
}
//------------------------------------------------------------------------------
void Box::Bottom_segment()
{
double bottom_seg_begin_w;
double bottom_seg_end_w;
bottom_seg_begin_w = xy.x + width_tenth;
bottom_seg_end_w = (xy.x + w) - width_tenth;
double y_bottom = xy.y + h;
Lines::add(Point(bottom_seg_begin_w,y_bottom),Point(bottom_seg_end_w,y_bottom));
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void Box::Left_side_segment()
{
double left_seg_begin_h;
double left_seg_end_h;
left_seg_begin_h = xy.y + width_tenth;
left_seg_end_h = (xy.y + h) - width_tenth;
double x_left = xy.x;
Lines::add(Point(x_left,left_seg_begin_h),Point(x_left,left_seg_end_h));
}
//------------------------------------------------------------------------------
void Box::Right_side_segment()
{
double right_seg_begin_h;
double right_seg_end_h;
right_seg_begin_h = xy.y + width_tenth;
right_seg_end_h = (xy.y + h) - width_tenth;
double x_right = xy.x + w;
Lines::add(Point(x_right,right_seg_begin_h),Point(x_right,right_seg_end_h));
}
//------------------------------------------------------------------------------
Use virtual inheritance for classes Lines and Arc. For example
class Lines : virtual public Shape
{
//...
};
class Arc : virtual public Shape
{
//...
};
How can I, using the draw() function of openframeworks, draw a square - ofRect (x, y, w, h) for x in x seconds?
I know it is possible since the draw uses fps but I do not know how to manipulate in order to do what I want.
Thank you!
One option is to interpolate based on time, not frame count using ofGetElapsedTimeMillis()
Another is to use a tweening/animation addon. You can find quite a few on ofxAddons in the animation section
You could do that in the simplest way:
int x = ofGetElapsedTimeMillis();
int y = 10;
int w = 100;
int h = 100;
ofDrawRectangle(x, y, w, h);
Note that in OpenFrameworks you should use ofDrawRectangle, it is different from ofRectangle.
If you want to reach more adivanced animations, I would recommend you to use ofxTweenzor addon, where you can manipulate variables in a period of time like this:
.h file:
#include "ofMain.h"
#include "ofxTweenzor.h"
class ofApp : public ofBaseApp{
public:
void setup();
void update();
void draw();
float x1;
};
.cpp file:
#include "testApp.h"
void ofApp::setup() {
Tweenzor::init();
float initialX = 0.f;
float finalX = 900.f;
float delay = 0.0f;
float durationInSeconds = 1.f;
Tweenzor::add(&x, initialX, finalX, delay, durationInSeconds );
}
void ofApp::update(){
Tweenzor::update( ofGetElapsedTimeMillis() );
}
void ofApp::draw() {
int y = 10;
int w = 100;
int h = 100;
ofDrawRectangle(x, y, w, h);
}
I have some question for coding C++ program with header file.
This is my header.h file :
#include <iostream>
using namespace std;
class Rectangle
{
public:
Rectangle(double width, double length);
double get_perimeter();
double get_area();
void resize(double factor);
private:
double width;
double length;
double area;
double factor;
};
And this is my Question1.cpp file which store all the methods:
#include <iostream>
using namespace std;
class Rectangle
{
public:
Rectangle(double width, double length)
{
width = width; //I have no idea how to use this.something as its in Java
length = length; //Problem probably occurs at here
}
double Rectangle::get_perimeter()
{
return ((width * 2) + (length * 2)) ;
}
double Rectangle::get_area()
{
return (width * length);
}
void Rectangle::resize(double factor)
{
width *= factor;
length *= factor;
}
private:
double width;
double length;
double area;
double factor;
};
And lastly, here is my main method.cpp :
#include <iostream>
#include "header.h";
using namespace std;
int main()
{
Rectangle rectangle1(2.5,7.0);
cout << rectangle1.get_perimeter();
cout << rectangle1.get_area();
system("PAUSE");
return 0;
}
However, when I try to run the program, the system told me that there was build errors and unresolved externals which I have no idea why is it so. Could somebody please help me fix it?
Thanks in advance.
Your implementations should not look like
class Rectangle
{
public:
Rectangle(double width, double length) { .... }
but like
Rectangle::Rectangle(double width, double length) : width(width), length(length) {}
You need to include header.h in the implementation .cpp file and in any file that needs the definition of the Rectangle class. You also need include guards in your headers. And do not put using namespace std in a header. In fact, don't put it anywhere.
Change .h to ->
#include <iostream>
using namespace std;
class Rectangle
{
public:
Rectangle(double width, double length);
double get_perimeter();
double get_area();
void resize(double factor);
private:
double width;
double length;
double area;
double factor;
};
Then .cpp to->
#include <iostream>
#include "header.h"
using namespace std;
Rectangle::Rectangle(double width, double length)
{
this->width = width; //I have no idea how to use this.something as its in Java
this->length = length; //Problem probably occurs at here
}
double Rectangle::get_perimeter()
{
return ((this->width * 2) + (this->length * 2)) ;
}
double Rectangle::get_area()
{
return (this->width * this->length);
}
void Rectangle::resize(double factor)
{
this->width *= factor;
this->length *= factor;
}
This should work then.
Regards,
Luka
Few things to unpick here.
1) use this->width which is equivalent to java's this.width (In C++, this is a pointer). Actually some C++ programmers (including me) prefix member variables with m_. Then you can just write m_width = width.
2) include "header.h" at the top of Question1.cpp
3) avoid putting "using namespace std" in a header file, or you could get unintended namespace
clashes as your code expands. OK to put it in the separate source files though although some folk even discourage this.
4) depending on your compiler and linker, you'll need to link to various lib's that the iostream library uses. Perhaps if you tell us the compiler you're using, we can help you here.
5) you need to surround your header with
#ifndef ARBITRARY_TEXT_BUT_DISTINCT_FROM_ANY_OTHER_IN_YOUR_PROGRAM
#define ARBITRARY_TEXT_BUT_DISTINCT_FROM_ANY_OTHER_IN_YOUR_PROGRAM
...your code here
#endif
This is an include guard - helps prevent multiple inclusion of a header file contents.
In Question1.cpp you have to include header.h
And don't forget include guards in header.h
Also in Question1.cpp you must change
Rectangle(double width, double length)
to
Rectangle::Rectangle(double width, double length)
You need to tell your build system to compile "question1.cpp". Usually there is an "add existing file to project" menu item somewhere under "File".
And typically, your class and constructor would use a different name than the input parameter. Many people put a prefix at the begginning (mLength, iLength) or postfix at the end (length_ is common).
The other solution is to prefix the member variable with this->length, but that can get pretty messy after a while.
the big mistake that in the .cpp file you are supposed to implement only the methods not rewrite full class implementation try the following in .cpp file
Rectangle::Rectangle(double width, double length)
{
width = width; //I have no idea how to use this.something as its in Java
length = length; //Problem probably occurs at here
}
and don't include the methods in class{}; block and don't redefine your member variables
also don't forget to include the header file in the .cpp file
thanks
I wonder if you are getting linker errors as your cpp file is little weird
In the cpp file include the .h file and only implement the functions like
Rectangle::Rectangle(double width, double length){
//implement
}
double Rectangle::get_perimeter(){
//implement
}
double Rectangle::get_area(){
//implement
}
void Rectangle::resize(double factor){
//implement
}
When you want to split your class file into a *.cpp and a *.h file it always has the following form:
rectangle.h:
#ifndef __RECTANGLE_H_
#define __RECTANGLE_H_
#include <iostream>
using namespace std;
class Rectangle
{
public:
Rectangle(double width, double length);
double get_perimeter();
double get_area();
void resize(double factor);
private:
double width;
double length;
double area;
double factor;
};
#endif
now the rectangle.cpp should have the following form:
#include <iostream>
#include "rectangle.h"
using namespace std;
Rectangle(double width, double length)
{
width = width; //I have no idea how to use this.something as its in Java
length = length; //Problem probably occurs at here
}
double Rectangle::get_perimeter()
{
return ((width * 2) + (length * 2)) ;
}
double Rectangle::get_area()
{
return (width * length);
}
void Rectangle::resize(double factor)
{
width *= factor;
length *= factor;
}
so when as an explanation:
The header file tells you which fields and methods are available and the *.cpp file implements the methods.
In your main.cpp you just need o include the rectangle.h
this code below works
#include<iostream>
#include<iomanip>
using namespace std;
class student
{
private:
int area;//hours;
float perimeter;//gpa;
public:
void addcourse(int len, float wid)
{
float sum;
sum = area * perimeter;
area += len;
sum += wid * len;
perimeter = sum / area;
}
student() // constructor
{
area = 0;
perimeter= 0.0;
}
};
int main()
{
student s;
int length;//classhours;//l
float width;//classgpa;//w
cout << "Enter length ( 1 to end): ";
cin >> length;
while(length != 1)
{
cout << "Enter width: ";
cin >> width;
s.addcourse(length, width);
cout << "Enter length ( 1 to end): ";
cin >> length;
}
// cout << "Rectangle's length = " << r.getlength() << endl;
// cout << "Rectangle's width = " << r.getwidth() << endl;
// cout << "Rectangle's area = " << r.getarea() << endl;
// cout << "Rectangle's perimeter = " << r.getperimeter() << endl;
}
I have made two files that are MathUtils.h
#include "iostream"
and MathUtils.cpp
#include "MathUtils.h"
using namespace std;
//Box class .....................
class Box
{
private:
double length; // Length of a box
double breadth; // Breadth of a box
double height; // Height of a box
public:
void setParameters(int l,int b,int h);
int volume();
int area();
};
void Box::setParameters(int l, int b, int h)
{
length=l;
breadth=b;
height=h;
}
int Box::volume()
{
return length*breadth*height;
}
int Box::area()
{
return (2*(length*breadth) + 2*(breadth*height) + 2*(height*length));
}
//sphere class................
class Sphere
{
private:
double pi=3.14;
double r;
public:
void setParameters(int radius);
int volume();
int area();
};
void Sphere::setParameters(int radius)
{
r=radius;
}
int Sphere::volume()
{
return (4/3)*pi*r*r;
}
int Sphere::area()
{
return 4*pi*r*r;
}
How can we use this file in my project could any one help me.I have never use c++ files in my project so I want to know how can we use Box and Sphere class object in other viewController file.
Thanks!.
You define your classes in the .h file.
For your example, move:
class Box
{
private:
double length; // Length of a box
double breadth; // Breadth of a box
double height; // Height of a box
public:
void setParameters(int l,int b,int h);
int volume();
int area();
};
class Sphere
{
private:
double pi=3.14;
double r;
public:
void setParameters(int radius);
int volume();
int area();
};
to mathutils.h and add #include "mathutils.h" to your viewController file. Your member functions for Box should still be in mathutils.c
A function in your view controller can then make use of it:
{
Box b;
b.setParameters(1,2,3);
int v = b.volume();
int a = b.area();
}