This is the beginning of my code that's supposed to be attached to a much larger code where I have to use 3 vectors to determine if I have a triangle, and if so, compute the area with multiple methods(like Heron's formula) for a homework assignment.
My main question is that, given the code below, which should result in sides with lengths of 5/4/3 respectively... why am I getting results of 4.6e-310/6.9e-310/0.
I am aware that my code may not be pretty, and may have gross conceptual errors, but I've only been learning C++ for 3 weeks after studying Fortran for a month.... and I feel super lost trying to do this.
#include <iostream>
#include <math.h>
// design vector class
class Vector {
private:
double Side1() {
return sqrt(pow(p1x-p2x,2)+pow(p1y-p2y));
}
double Side2() {
return sqrt(pow(p2x-p3x,2)+pow(p2y-p3y,2));
}
double Side3() {
return sqrt(pow(p3x-p1x,2)+pow(p3y-p1y,2));
}
public:
double p1x=1.0, p2x=4.0, p3x=4.0;
double p1y=5.0, p2y=9.0, p3y=5.0;
};
// get length
int main() {
double Side1, Side2, Side3;
std::cout << "Side 1 length is " << Side1 << std::endl;
std::cout << "Side 2 length is " << Side2 << std::endl;
std::cout << "Side 3 length is " << Side3 << std::endl;
return 0;
}
There is a couple of errors in your code:
First, your functions are private. This means you cannot ever call these functions, except from within another function of this class. You probably meant to have public funtions and private data members instead:
class Vector {
public:
double Side1() {
return sqrt(pow(p1x-p2x,2)+pow(p1y-p2y));
}
double Side2() {
return sqrt(pow(p2x-p3x,2)+pow(p2y-p3y,2));
}
double Side3() {
return sqrt(pow(p3x-p1x,2)+pow(p3y-p1y,2));
}
private:
double p1x=1.0, p2x=4.0, p3x=4.0;
double p1y=5.0, p2y=9.0, p3y=5.0;
};
Second, you need an object of the type Vector (because your functions are not static members of this class). Then, on this object, you need to call your methods.
int main() {
Vector v; // create object
std::cout << "Side 1 length is " << v.Side1() << std::endl; //note the call operator ()
std::cout << "Side 2 length is " << v.Side2() << std::endl;
std::cout << "Side 3 length is " << v.Side3() << std::endl;
return 0;
}
Your current code creates 3 unitialized double variables, which have nothing in common with your functions (they just share the name).
Related
I have the following problem: I wanted to redo a project from good old C to C++ and make everything class(y) :) and keep it scalable from the beginning.
It is a simulation of cells (being part of a swarm) on a grid, so I decided the following structure:
class Simulation has an instance of
class Grid has an instance of
class Swarm has an instance of
class Cell
I defined the classes in separate header files. Then I need, of course, to be able to call functions in grid, swarm and cell as well. I wanted to do it straight forward:
Simulation mysim;
mysim.get_grid(0).any_function_here();
with the grid as return parameter
Grid Sim::get_grid(int grid_no)
{
std::cout << "sim.get_grid(" << grid_no << ") called." << std::endl;
if (grid_no <= amount_of_grids)
return this->test;//##//this->gridlist[grid_no];
else
std::cout << "you have not created this grid number yet" << std::endl;
Grid dummy;
return dummy;
}
It calls the function and works as long as no changes in the grid are made. These seem to be lost in space. Probably a pointer error, but I cannot find an error, since exactly the same code is working for the Simulation class...
More source:
int Grid::create_swarm(std::string name)
{
Swarm new_swarm;
new_swarm.set_name("Protoswarm");
swarmlist.push_back(new_swarm);
this->amount_of_swarms ++;
std::cout << "amount_of_swarms = " << amount_of_swarms << std::endl;
return 0;
}
Swarm Grid::get_swarm(int swarm_no)
{
std::cout << "grid.get_swarm(" << swarm_no << ") called." << std::endl;
if (swarm_no <= amount_of_swarms)
return swarmlist[swarm_no];
else
std::cout << "oh oh - you have not this swarm in here..." << std::endl;
Swarm dummy;
return dummy;
}
I can call the create_swarm function as often as I want, but the swarms do never appear and the counter does not raise in that grid, just temporarily as long as the funtion is in there. Am I missing something? Is it really just a pointer error? Why does this code work if I call it like this:
Grid newgrid;
newgrid.create_swarm();
A quickly c&p'ed MWE
#include <iostream>
#include <string>
#include <vector>
class Sim
{
public:
Sim();
virtual ~Sim();
Grid get_grid(int grid_no);
protected:
private:
std::vector<Grid> gridlist;
int amount_of_grids = -1;
};
class Grid
{
public:
Grid();
virtual ~Grid();
int set_size(int x, int y);
int create_swarm(std::string name);
Swarm get_swarm(int swarm_no);
void print_swarms();
protected:
private:
std::vector<Swarm> swarmlist;
int amount_of_swarms = -1;
/*static const*/ int size_x;
/*static const*/ int size_y;
std::vector<std::vector<Field>> fields;
std::string gridname;
};
Grid Sim::get_grid(int grid_no)
{
std::cout << "sim.get_grid(" << grid_no << ") called." << std::endl;
if (grid_no <= amount_of_grids)
return this->gridlist[grid_no];
else
std::cout << "you have not created this grid number yet" << std::endl;
Grid dummy;
return dummy;
}
int Grid::create_swarm(std::string name)
{
Swarm new_swarm;
new_swarm.set_name("Protoswarm");
swarmlist.push_back(new_swarm);
this->amount_of_swarms ++;
std::cout << "amount_of_swarms = " << amount_of_swarms << std::endl;
return 0;
}
Swarm Grid::get_swarm(int swarm_no)
{
std::cout << "grid.get_swarm(" << swarm_no << ") called." << std::endl;
if (swarm_no <= amount_of_swarms)
return swarmlist[swarm_no];
else
std::cout << "oh oh - you have not this swarm in here..." << std::endl;
Swarm dummy;
return dummy;
}
using namespace std;
int main(int argc, char* argv[])
{
Sim mysim;
mysim.create_grid();
mysim.get_grid(0).create_swarm("Alpha-Swarm");
mysim.get_grid(0).create_swarm("Betaa-Swarm"); //doesn't work
Grid newgrid;
newgrid.create_swarm("Gamma-Swarm");
newgrid.create_swarm("Delta-Swarm"); // works, but is not needed.
return 0;
}
Grid Sim::get_grid(int grid_no) {...}
You are returning by value, not by reference. That means that what you are returning is a copy of your actual member. In your case, however, you want to be returning by reference in order to be able to make changes to the original object. Your code would become
Grid& Sim::get_grid(int grid_no) {...}
Keep in mind, however, that you will not be able to return any temporaries that way (such as your dummy Grid), so you will need to change your methods to circumvent this issue. If you do not want to do this, you could still return a pointer, although this would change the syntax a little.
Your get_grid and get_swarm methods return copies of original array items. You should return reference (or a pointer) to Grid or Swarm instead.
I am very new to programming, and am near the end of this program, but cannot quite finish the last detail, which I have been stuck on. I am attempting to switch what shape pointer *sp is pointing to, and it seems to me that what I am doing should work, since rectangle and circle both are shapes; however, when I compile, only the value of the color changes. The area of the circle prints instead of the area of the rectangle and the perimeter prints 0. Any help would be greatly appreciated!
#include <iostream>
#include <string>
using namespace std;
double const pi = 3.1519;
class shape {
public:
shape() {};
shape(string);
virtual double getCircumference() {
return 0;
};
virtual double getPerimeter() {
return 0;
};
virtual double getArea() {
return 0;
};
string getColor();
protected:
string color;
};
string shape::getColor() {
return color;
}
class circle : public shape {
public:
circle(double r, string c) {
radius = r;
color = c;
};
double getArea();
double getCircumference();
private:
double radius;
};
double circle::getCircumference() {
return pi * radius * 2;
}
double circle::getArea() {
return pi * radius * radius;
}
class rectangle:public shape {
public:
rectangle(double w, double l, string c) {
width = w;
length = l;
color = c;
};
double getArea();
double getPerimeter();
private:
double length;
double width;
};
double rectangle::getPerimeter() {
return width * 2 + length * 2;
}
double rectangle::getArea() {
return length * width;
}
void change(shape *sp, shape *sp1) {
*sp = *sp1;
}
int main() {
circle mary(3.2, "Green");
shape *sp = new circle(4.5, "Yellow");
cout << "Circle #1 is " << mary.getColor() << endl;
cout << "Circle #1 has an area of " << mary.getArea() << endl;
cout << "Circle #1 has a circumference of " << mary.getCircumference() << endl << endl;
cout << "Circle #2 is " << sp->getColor() << endl;
cout << "Circle #2 has an area of " << sp->getArea() << endl;
cout << "Circle #2 has a circumference of " << sp->getCircumference() << endl << endl;
shape *sp1 = new rectangle(1.0, 2.1, "Red");
change(sp, sp1);
cout << "Rectangle #1 is " << sp->getColor() << endl;
cout << "Rectangle #1 has an area of " << sp->getArea() << endl;
cout << "Rectangle #1 has a perimeter of " << sp->getPerimeter() <<endl<< endl;
}
It’s important to keep in mind what is meant by various different ways of using pointers. In your program, sp refers to the pointer itself—that is, a memory location telling the computer where to find an object. The asterisk in *sp is a ‘dereference’ operator; it takes a pointer and gives you the thing that it is pointing to.
With this in mind, your line *sp = *sp1; is saying, ‘take the thing that sp is pointing to, and set it to be equal to the thing that sp1 is pointing to.’ In other words, you are changing the value of the object pointed to by sp, not the value of sp itself. To point sp at the object pointed to by sp1, you need sp = sp1; with no asterisks.
The other thing to bear in mind is that C++ by default passes function arguments by value: when the function is called, the arguments are copied, and the function operates on the copies. This means that the original arguments themselves cannot be changed by a function that works like this. Adding an ampersand to the argument declaration, like void change(shape *&sp, shape *sp1) causes the first argument to be passed by reference: the object operated on by the function is the same object that was passed in by the calling code. This allows the function to change objects passed as arguments, and for those changes to remain after the function has returned.
Sorry for the long answer: I could have given you a few lines that did what you wanted, but I thought you might appreciate an explanation of the reason why things work the way they do.
If you are trying to change the address of pointers, you must pass pointers by reference. Try this:
void change(shape *&sp, shape *&sp1)
A pointer is passed by value even if it's a pointer.
This means that you are actually passing the address by value, so the argument is a copy of the original argument.
Think about
void sum(int a, int b, int result);
void foo() {
int result;
sum(5,10,result);
}
While you expect to be able to store the result into the variable passed to the sum argument you won't be able to do it since result is passed by value and hence copied. Every modification you do to result inside the method will be local to the method.
That's exactly the same thing, a pointer is nothing more than an address, if you pass it by value then a copy of the address is passed but every modification to the local variable is just local.
That's why you must use references if you want to be able to modify their values, exactly as every other variable, so you would have
void sum(int a, int b, int& result);
void change(shape*& shape1, shape*& shape2);
This, under the hood, will pass the address to the variable which stores the address (a sort of shape**) so the function is able to know where the original argument is located and modify it directly.
Hello I have two questions. First, here is some code. I am new to c++. I have to calculate the square of rectangle by the x,y coordinates of upper left and lower right corner - downRightx, upperLeftx, downRighty, upperLefty, the diagonal, and the sides of rectangle. I must make a function print() that calls other private functions only to show the result. Everything is defined inside the class.
class rectangle {
private:
double uLx, uLy, dRx, dRy;
public:
rectangle() {
cout << "enter x coordinate of upper left corner" << uLx;
cout << "enter y coordinate of upper left corner" << uLy;
cout << "enter x coordinate of down right corner" << dRx;
cout << "enter y coordinate of down right corner" << dRy;
}
~rectangle() {
cout << "Deleting object" << endl;
}
private:
void sides() {
double a, b;
a = sqrt(pow((dRx - uLx), 2));
b = sqrt(pow((dRy - uLy), 2));
}
void facediag() {
double s, d;
d = sqrt(pow((dRx - uLx), 2) + pow((dRy - uLy), 2));
---- 1. //here must be the calculation of square s = a*b
}
public:
void print() {
--- 2. //here I must print the results
}
};
so the question is: How to call a and b parameters from side in facediag() function to calculate s = a*b And how to print the results. Can I write cout << a; cout << d; cout << s, etc. in sides() and facediag() and just call them in print? Or can I print them in print() without writing cout << ... in other functions, but otherwise, another access method.
void facediag(){
//code
cout << s;
cout << d;
}
void sides(){
// code
cout << a;
cout << b;
}
void print()
{
sides();
facediag();
}// not like this, is there another way?
Second question I let Cygwin to be installed at its complete form and at some point I realized that I will run out of hdd and the installation hangs, so I interrupted the installation. How can I uninstall it - just delete the folder or to step through the FAQ in the Cygwin site?
You cannot access local variables from other functions. They only exist while that function executes.
What you can do is define more member functions that compute the values you need, like
double height() const
{ return /* something */; }
double width() const
{ return /* something else */; }
and use those functions where you need a or b.
You CAN call the private function in your OWN class.
But, the variable a and b are local variables, so they will not exist out of the function sides(), you can do the same thing in function facediag() to calculate a and b
This question already has answers here:
Uninitialized values being initialized?
(7 answers)
Closed 8 years ago.
I'm doing some testing...
Firstly I post my source code
the .h file
class Complex{
private:
int r = 0;//initializer
int i ;
public:
Complex(int , int I = 0);
Complex();
void print();
void set(int, int I = 1);
static void print_count();
static int count;
};
the .cpp file
#include <iostream>
#include "complex.h"
int Complex::count = 1;
Complex::Complex(int R , int I){
r = R;
i = I;
count++;
std::cout << "constructing Complex object...count is " << Complex::count << std::endl;
}
Complex::Complex(){//default constructor
std::cout << "default constructor is called..." << std::endl;
}
void Complex::print(){
std::cout << "r = " << r << ';' << "i = " << i << std::endl;
return;
}
void Complex::set(int R, int I /*= 2*/){//will be "redefaulting", an error
r = R;
i = I;
return;
}
void Complex::print_count(){//static
Complex::count = -1;//jsut for signaling...
std::cout << "count is " << count << std::endl;
return;
}
the main function
#include <iostream>
#include "complex.h"
int main(){
Complex d;//using default constructor
d.print();
/*Complex c(4, 5);*/
Complex c(4);
//c.print();
/*c.set(2, 3)*/
c.print();
c.set(2 );
c.print();
std::cout << "count is " << c.count << std::endl;//c can access member data
c.print_count();
c.count++;//
return 0;
}
consider the Complex object d constructed with default ctor
because the data member r is initialized using with 0, when executing d.print(),
r is expected to be 0
and i isn't, so I expected it to be garbage value
but when I'm testing, one strange thing happens.
if I eliminate this and the following lines of code in the main file:
std::cout << "count is " << c.count << std::endl;//c can access member data
then d.print() will give the value of i as 32767 on my system, which I guess it's a garbage value;
but once that line is added, d.print() just give i's value to 0 on my system.
I don't get it. I hasn't set, modiify or initialize i's value, why should it be 0?
or, it is also a garbage value?
or, calling one of those function corrupts the value of i?
how is the thing run behind the scene here?
thx for helping.
0 is just as garbage value as any other. Don't make the mistake of thinking otherwise.
Formally, reading an uninitialized variable is undefined behavior, so there's no point in wondering about it: just fix it by initializing the variable properly.
I'm working my way through Accelerated C++ and have decided to mess around with the one of structs that were defined in there. While doing so, I've come across a problem: creating a vector of these structs and modifying the elements in each one seems to modify the elements in all of them.
I realize that this probably means I've initialized all the structs in the vector to a struct at a single memory address, but I used the .push_back() method to insert "dummy" structs in to the vector. I was under the impression that .push_back() pushes a copy of its argument, effectively creating a new struct.
Here is the header for the struct:
#ifndef _STUDENT_INFO__CHAPTER_9_H
#define _STUDENT_INFO__CHAPTER_9_H
#include <string>
#include <iostream>
#include <vector>
class Student_info9{
public:
Student_info9(){homework = new std::vector<double>;};
Student_info9(std::istream& is);
std::string getName() const {return name;};
double getMidterm() const {return midterm;};
double getFinal() const {return final;};
char getPassFail() const {return passFail;};
std::vector<double> *getHw(){return homework;};
void setName(std::string n) {name = n;};
void setMidterm(double m) {midterm = m;};
void setFinal(double f) {final = f;};
private:
std::string name;
double midterm;
double final;
char passFail;
std::vector<double> *homework;
};
#endif /* _STUDENT_INFO__CHAPTER_9_H */
And here is the code that i'm fooling around with (excuse the excessive print statements... the result of some time trying to debug :) ):
vector<Student_info9> did9, didnt9;
bool did_all_hw9(Student_info9& s)
{
vector<double>::const_iterator beginCpy = s.getHw()->begin();
vector<double>::const_iterator endCpy = s.getHw()->end();
return(find(beginCpy, endCpy, 0) == s.getHw()->end());
}
void fill_did_and_didnt9(vector<Student_info9> allRecords)
{
vector<Student_info9>::iterator firstDidnt = partition(allRecords.begin(), allRecords.end(), did_all_hw9);
vector<Student_info9> didcpy(allRecords.begin(), firstDidnt);
did9 = didcpy;
vector<Student_info9> didntcpy(firstDidnt, allRecords.end());
didnt9 = didntcpy;
}
int main(int argc, char** argv) {
vector<Student_info9> students;
Student_info9 record;
for(int i = 0; i < 5; i++)
{
students.push_back(record);
}
for(int i = 0; i < students.size(); i++)
{
students[i].setMidterm(85);
students[i].setFinal(90);
students[i].getHw()->push_back(90);
std::cout << "student[" << i << "]'s homework vector size is " << students[i].getHw()->size() << std::endl;
students[i].getHw()->push_back(80);
std::cout << "student[" << i << "]'s homework vector size is " << students[i].getHw()->size() << std::endl;
students[i].getHw()->push_back(70);
std::cout << "student[" << i << "]'s homework vector size is " << students[i].getHw()->size() << std::endl;
std::cout << "Just pushed back students[" << i << "]'s homework grades" << std::endl;
if(i == 3)
students[i].getHw()->push_back(0);
}
std::cout << "student[3]'s homework vector size is " << students[3].getHw()->size() << std::endl;
for(vector<double>::const_iterator it = students[3].getHw()->begin(); it != students[3].getHw()->end(); it++)
std::cout << *it << " ";
std::cout << std::endl;
std::cout << "students[3] has " << ( ( find(students[3].getHw()->begin(),students[3].getHw()->end(), 0) != students[3].getHw()->end()) ? "atleast one " : "no " )
<< "homework with a grade of 0" << std::endl;
fill_did_and_didnt9(students);
std::cout << "did9's size is: " << did9.size() << std::endl;
std::cout << "didnt9's size is: " << didnt9.size() << std::endl;
}
As you can see by the print statements, it seems that the homework grades are being added only to one Student_info9 object, copies of which seem to be populating the entire vector. I was under the impression that if you were to use consecutive copies of .push_back() on a single object, it would create copies of that object, each with different memory addresses.
I'm not sure if that's the source of the problem, but hopefully someone could point me in the right direction.
Thanks.
When you push a StudentInfo onto the vector, it is indeed copied, so that's not the problem. The problem is the vector containing the homework grades. Since you only store a pointer to that vector in StudentInfo, only the pointer, not the vector, is copied when you copy a StudentInfo. In other words you have many different StudentInfos that all have a pointer to the same homework vector.
To fix this you should define a copy constructor which takes care of copying the homework vector.
Have you learned about the copy constructor yet? If so, think about what is happening with vector<Student_info9> students on push_back().
Specifically, what happens with this pointer.
std::vector<double> *homework;
The line Student_info9 record; constructs a Student_info9 using the first constructor. This first constructor creates a vector and stores a pointer to it as a member variable. You then proceed to add a copy of this Student_info9 to a vector 5 times. Each copy has a pointer to the same vector.
Your StudentInfo9 class contanis a pointer to a std::vector<double>, which means in the default copy constructor (which will be called when you add a StudentInfo9 object to your vector), the pointer itself is copied. That means all of your StudentInfo9 objects have the same homework vector.
Does that make sense? Please refer to http://pages.cs.wisc.edu/~hasti/cs368/CppTutorial/NOTES/CLASSES-PTRS.html for a more in depth look at pointers and copy constructors.