Accessing class pointers across several functions - c++

I have a problem I've been stuck on for a while trying to make my code more efficient. I've created a Vector class and need to do some basic calculation with it. Using a vector library is out of the question, I need to create my own.
The problem I have currently is in the final stage of the math. I can enter values for the first and second vector, but upon adding them together I get completely random numbers. I'm posting my header file and my cpp file - any help will be appreciated!!
Vectors.h
#include <math.h>
#include <iostream>
class Vectors
{
public:
Vectors(void);
~Vectors(void);
Vectors(double a1, double b1, double c1, double d1)
{
a = a1;
b = b1;
c = c1;
d = d1;
}
void VectorAdd(Vectors vector1, Vectors vector2);
void VectorSub();
void VectorMulti();
void VectorDiv();
void VectorDP();
void VectorCP();
void setV1(Vectors &vector1);
void setV2(Vectors &vector2);
private:
double a;
double b;
double c;
double d;
double cp;
};
Cpp file
void Vectors::setV1(Vectors &vector1)
{
Vectors *Vector1 = new Vectors();
std::cout << "Enter the values of the first vector please.\n";
std::cout << "a1: ";
std::cin >> Vector1 -> a;
std::cout << "b1: ";
std::cin >> Vector1 -> b;
std::cout << "c1: ";
std::cin >> Vector1 -> c;
std::cout << "d1: ";
std::cin >> Vector1 -> d;
Vector1 = &vector1;
std::cin.get();
std::cin.get();
}
void Vectors::setV2(Vectors &vector2)
{
Vectors *Vector2 = new Vectors();
std::cout << "Enter the values of the first vector please.\n";
std::cout << "a1: ";
std::cin >> Vector2 -> a;
std::cout << "b1: ";
std::cin >> Vector2 -> b;
std::cout << "c1: ";
std::cin >> Vector2 -> c;
std::cout << "d1: ";
std::cin >> Vector2 -> d;
Vector2 = &vector2;
std::cin.get();
std::cin.get();
}
void Vectors::VectorAdd(Vectors vector1, Vectors vector2)
{
setV1(vector1);
setV2(vector2);
Vectors *Vector3 = new Vectors();
std::cout << "Here is the combination of the two vectors.\n";
Vector3 -> a = vector1.a + vector2.a;
std::cout << "a3: " << Vector3 -> a;
Vector3 -> b = vector1.b + vector2.b;
std::cout << "\nb3: " << Vector3 -> b;
Vector3 -> c = vector1.c + vector2.c;
std::cout << "\nc3: " << Vector3 -> c;
Vector3 -> d = vector1.d + vector2.d;
std::cout << "\nd3: " << Vector3 -> d;
std::cin.get();
std::cin.get();
}
Thank you in advance!

Vector2 = &vector2;
You did this backwards. You've overwritten the pointer to a new object you just initialized with a pointer to a completely uninitialized object, that you passed in here. The random data is in the uninitialized object, of course.
You don't need the
Vectors *Vector2 = new Vectors();
in the first place. Just initialize the vector2 parameter, directly, from std::cin. Ditto for the other function, setV1(), as well. Same thing.

I think the problem here is, you are confusing with pointer & reference.
In void Vectors::setV1(Vectors &vector1), you are getting vector1 as reference.
Next, you are creating a brand new object Vectors *Vector1 = new Vectors();. And then you are continuing to fill *Vector1. Till this point, I don't see anything weird. However, this part Vector1 = &vector1; totally damages the program. You are now re-assigning the pointer Vector1 with incoming address of vector1.
Unless you have some value on the memory as pointed by vector1 you are not going to have correct results. Infact you are lucky, as you didn't say, your program generated SIGSEGV :)

Related

c++ entering values two times instead of one

I have to solve this " create class for describing triangle and trapeze with ability to return values and finding S of the figures.. declare function which allows comparing S of the both figures.. in main function declare object triangle and trapeze and compare their areas .. " - im trying to translate it from Bulgarian to English sorry if its not translated correctly ..
Anyways I came up with a solution, but when it asks me to enter value for trapeze x2 times and I can't understand why... it always takes the first 3 entered numbers but I want it to ask for input only once .. sorry if the answer is obvious
//
// main.cpp
// compare S of 2 figures
//
// Created by Георгиос Семерджиев on 17/05/22.
//
#include <iostream>
#include <cmath>
using namespace std;
class Trap // trap class with declared functions inside
{
protected:
double a, c, h;
void setValueTrap();
public:
Trap();
void Print();
virtual double S();
}; // end trap class
class Triangle : public Trap // triangle class with declared function for finding s() print and setting value
{
double b;
void setValueTriangle();
public:
Triangle();
void Print();
virtual double S();
double p(); // returning P/2
}; // end triangle class
// trap functions ...
Trap:: Trap()
{
setValueTrap();
}
void Trap::setValueTrap() // trap input function
{
cout << "Trap enter a = "; cin >> a;
cout << "Trap enter c = "; cin >> c;
cout << "Trap enter h = "; cin >> h;
cout << endl;
}
double Trap::S() // trap calculating and returning s()
{
return ( (a+c) * h ) / 2;
}
void Trap::Print() // printing S() for trap
{
cout << "Trap S = " << S();
cout << endl;
}
// Triangle functions ..
Triangle::Triangle():Trap()
{
setValueTriangle();
}
void Triangle::setValueTriangle() // setting value for triangle a,b,c
{
cout << "Triangle a = "; cin >> a;
cout << "Triangle b = "; cin >> b;
cout << "Triangle c = "; cin >> c;
cout << endl;
}
double Triangle::p() // returning P / 2 = p
{
return (a+b+c) / 2;
}
double Triangle::S() // calculating S() of triangle
{
return sqrt(p() * (p() - a) * (p()-b) * (p()-c));
}
void Triangle::Print()
{
cout << "Triangle S = " << S();
cout << endl;
}
// creating function to compare Trap S() and Triangle S()
bool Compare (Trap *F1, Trap *F2)
{
return F1 -> S() < F2 -> S();
} // compare function
int main()
{
Trap* trap = new Trap();
Triangle* triangle = new Triangle();
trap -> Print(); triangle -> Print();
cout << endl;
if (Compare(trap, triangle))
cout << "the Trap S < Triangle S.." << endl;
else
{
cout << "The Trap S > Triangle S.." << endl;
}
return 0;
}
For the Triangle constructor you have:
Triangle::Triangle():Trap()
{
setValueTriangle();
}
That will explicitly invoke the Trap constructor which read input. Then you will read the input for the triangle.
It's often not a good idea to read input in a constructor. It's usually better to only do basic initialization in the constructor and then get input using the fully constructed object.
Note that even if you don't have the explicit invokation of the Trap constructor, this will happen implicitly.
Triangle inherits from Trap, and both of their constructors are called when constructing Triangle object. To avoid this set up a virtual function setValue and call it only in Trap constructor.

Fill a vector with references to another vector

I have a vector of Structs that represent points (allPoints). This vector contains the entire collection of points on a given plane (in this example it contains four points). Each struct contains a pair of integers representing a point, a flag, as well as another vector of points which contains every other point on the plane.
What I want to do is select a point from the preference list of a point, change its flag, and have this change apply to the point in the allPoints vector. I imagine I need a vector of references or something similar. Here is an example of what I am talking about:
#include <iostream>
#include <string>
#include <vector>
#include <utility>
using namespace std;
struct Point {
pair<int,int> p;
vector<Point> prefs;
bool flag = true;
};
void fillVectors(vector<Point> & allPoints);
void printState(vector<Point> & allPoints);
int main()
{
vector<Point> allPoints;
fillVectors(allPoints);
printState(allPoints);
// I want to go into the preference list of any given point, select a point, and change its flag. This change
// should be reflected in the allPoints vector, not just the preferences vector
allPoints[0].prefs[2].flag = false;
printState(allPoints);
// The flags have not changed. If I searh for the point in allPoints, then change the flag, it will change
for(Point p : allPoints)
{
if(p.p == allPoints[0].prefs[2].p) allPoints[0].flag = false;
}
printState(allPoints);
}
void fillVectors(vector<Point> & allPoints)
{
pair<int,int> p1 = make_pair(0,0);
pair<int,int> p2 = make_pair(5,0);
pair<int,int> p3 = make_pair(3,7);
pair<int,int> p4 = make_pair(2,9);
vector<pair<int,int>> coords = {p1, p2, p3, p4};
for(int i = 0; i < coords.size(); i++)
{
Point newPoint;
newPoint.p = coords[i];
allPoints.push_back(newPoint);
}
// Fill the preference lists with every other point (in no particular order)
for(int i = 0; i < allPoints.size(); i++)
{
for(int j = 0; j < allPoints.size(); j++)
{
if(i == j) continue; // Do not put a point in its own preference list
allPoints[i].prefs.push_back(allPoints[j]);
}
}
}
void printState(vector<Point> & allPoints)
{
cout << "Contents of all points:\n";
for(Point p : allPoints)
cout << "point: (" << p.p.first << "," << p.p.second << ")" << " Flagged? -> " << p.flag << "\n";
cout << "~\nContents of each preference vector:\n";
for(Point p : allPoints)
{
cout << "point: (" << p.p.first << "," << p.p.second << ")\tprefs: ";
for(Point q : p.prefs)
cout << "(" << q.p.first << "," << q.p.second << "), ";
cout << "\n";
}
cout << "--------------------\n";
}
Here, I have allPoints which holds four pairs. The print state function prints every point from the all points along with its flag, then the preference list of each point. What I need is for the prefs vector in each point to hold references to that point object in the allPoints vector. Instead, it just seems to be making a copy.
I want do to this so that I can change point flags in O(1) time, rather than the O(n) time it takes to get the point from the preferences, then search for it in allPoints and change it
If the only part of state which you want to be shared is flag and if you do not plan to change value of Point::p member once object created, you can replace bool flag with std::shared_ptr<bool> flag and when copies are created - shared_ptr will be copied and it will hold the value shared between objects.
struct Point
{
Point(const std::pair<int,int>& value)
: p(value)
{}
Point(const Point&) = default;
Point& operator = (const Point&) = default;
const std::pair<int,int> p;
vector<Point> prefs;
std::shared_ptr<bool> flag = std::make_shared<bool>(true);
};
Then if you will do:
Point pt1({1,2});
auto pt2 = pt1;
std::cout << *pt2.flag << " ";
*pt1.flag = false;
std::cout << *pt2.flag << " ";
the output will be "1 0" since pt1 and pt2 objects share same bool.
Note: if there is no const for Point::p then it's possible to change it's value after copies from object are created - in this case sharing flag for such objects makes no sense.
Of course, that would be easy to break given all members are public, so you'll need to access flag carefully. To make this code safe - encapsulation should be used.

Assignment operator overloading: returning void versus returning reference parameter [duplicate]

This question already has answers here:
Why should the assignment operator return a reference to the object?
(4 answers)
Closed 6 years ago.
Some of the assignment overloading operator examples I see online look like this:
#include <iostream>
using namespace std;
class Distance {
private:
int feet; // 0 to infinite
int inches; // 0 to 12
public:
// required constructors
Distance(){
feet = 0;
inches = 0;
}
Distance(int f, int i){
feet = f;
inches = i;
}
void operator = (const Distance &D ) {
cout << "assigning..." << endl;
feet = D.feet;
inches = D.inches;
}
// method to display distance
void displayDistance() {
cout << "F: " << feet << " I:" << inches << endl;
}
};
int main() {
Distance D1(11, 10), D2(5, 11);
cout << "First Distance : ";
D1.displayDistance();
cout << "Second Distance :";
D2.displayDistance();
// use assignment operator
D1 = D2;
cout << "First Distance :";
D1.displayDistance();
return 0;
}
They return void from the overloaded function. This makes sense to me if D1 is the object being called.
Other examples return a reference to a class object.
#include <iostream>
using namespace std;
class Distance {
private:
int feet; // 0 to infinite
int inches; // 0 to 12
public:
// required constructors
Distance(){
feet = 0;
inches = 0;
}
Distance(int f, int i){
feet = f;
inches = i;
}
Distance& operator = (const Distance &D ) {
cout << "assigning..." << endl;
feet = D.feet;
inches = D.inches;
return *this;
}
// method to display distance
void displayDistance() {
cout << "F: " << feet << " I:" << inches << endl;
}
};
int main() {
Distance D1(11, 10), D2(5, 11);
cout << "First Distance : ";
D1.displayDistance();
cout << "Second Distance :";
D2.displayDistance();
// use assignment operator
D1 = D2;
cout << "First Distance :";
D1.displayDistance();
return 0;
}
This does not make sense to me (when taking the first example into consideration). If in the first example D1 = D2; invokes something like D1.=(D2);, why would the second example work in that case? Is it something like D1 = D1.=(D2);? And does it make any difference at the end of the day?
Although C++ language lets you overload assignment operator with any return type, including void, you should strongly consider following a widespread convention of returning a reference to the assignee from the operator.
The rationale for it is that
A = B;
will work no matter what the assignment returns, while
A = B = C;
which is a perfect chain of assignments will break, unless B = C returns something assignment-compatible to A (which is usually an object of the same type as A).
Another problem is in situations when you must compare the object as part of a larger expression, for example
mytype obj;
while ((obj = read_obj(cin)) != END_OBJ) {
...
}
Hence, the biggest drawback to returning void is inability to chain assignments and use them in places where void is not allowed.
As a convention, assignment operator usually returns reference (to *this); which makes it possible to chain the assignment, just like the behavior of those built-in types. e.g.
Distance D1, D2, D3;
D1 = D2 = D3;
For D1 = D2;, it's equivalent with D1.operator=(D2);. It doesn't change for the 2nd case, the returned value is just discarded. For D1 = D2 = D3;, it's equivalent with D1.operator=(D2.operator=(D3));. Note the returned value (i.e. reference to D2) is used as the argument for the assignment operator called on D1.

How is "a" used in my program?

new to learning c++ and I was wanting to understand the program ive practiced. I have a section of code I want to understand but im kind of lost.
#include "stdafx.h";
#include <iostream>;
// getValueFromUser will read a value in from the user, and return it to the caller
int getValueFromUser()
{
std::cout << "Enter an integer: ";
int a;
std::cin >> a;
return a;
}
int main()
{
int x = getValueFromUser(); // first call to getValueFromUser
int y = getValueFromUser(); // second vall to getValueFromUser
std::cout << x << " + " << y << " = " << x + y << std::endl;
return 0;
}
Im just wanting to know how " int a " comes into play here. If someone could help it would be appreciated.
You declare an uninitialized variable of type int with identifier a:
int a;
The user provides a value to a.
std::cin >> a;
A copy is returned from the function:
return a;
Calls to the getValueFromUser() will create a temporary a,
assign it to user input, and return it each time.
In c++ you have to declare variable (providing the type and name) before it's first use.
std::cin has to put it's output somewhere and that's why you need this additional variable.

Combining overloaded operators with 'new' object

i'd like to ask something rather difficult for me; I have to make a calendar-type program, but with an overloaded '+=' operator.
So it goes like this:
template<typename T1,typename T2,typename T3> //int,int,int
class T_sort_data{
T1 p1;
T2 p2;
T3 p3;
public:
T_sort_data(){
cout << "\n\t Constructed at [" << this << "]\n";};
/ friend ostream& operator<<(ostream& os,const T_sort_data& obj) // get function
{
os << "\nDay : " << obj.p1 << " \n";
os << "Month : " << obj.p2 << " \n";
os << "Year : " << obj.p3 << " \n";
return os;
}*/
void set_date(){
int dd,mm,yy;
cout << "\n\n\tPlease input the day, the month and the year : \n\n";
cin >> dd >> mm >> yy;
p1 = dd;
p2 = mm;
p3 = yy;
}
// validator here, which works ...
T_sort_data<int,int,int>& operator+=(const T_sort_data<int,int,int>& second)
{
p1+=second.p1;
return *this;
}
friend istream& operator>>(istream& is, T_sort_data& obj) // set function
{
is >> obj.p1;
is >> obj.p2;
is >> obj.p3;
return is;
}
~T_sort_data(){
cout << "\n\t Deconstructed [" << this << "]\n";};
};
int main(){
T_sort_data<int,int,int> * a = new T_sort_data<int,int,int> ;
bool more = true;
string answ;
a->set_date();
//cin >> a; (this doesn't work)
//validator goes here
//a += a; (this, again, doesn't work)
delete a;
return 0;
}
Whenever I make an object using "T_sort_data a;" those operations work fine, but whenever I use "T_sort_data * a = new T_sort_data;"
shit hits the fan.
Can anyone help me with this?
You didn't post exactly what is going wrong so I have to infer that from the code.
The issue that you're running into is that overloaded operators work on instances or references to objects, not on pointers to objects. In the cases where your code doesn't work, you're dealing with pointers to objects. So, in order to use your overloaded operators, you need to dereference the pointer (effectively turning it from a pointer pointing to a value into the value itself) before applying the operator, for example:
cin >> *a;
or
*a += *a;
T_sort_data a is a variable of type T_sort_data.
T_sort_data * a is a variable of type pointer to T_sort_data.
Your overloaded operators expect their operands to be of type T_sort_data, not pointer to T_sort_data. Use the unary * operator to dereference the pointers, so that the operand types are what the operators expect.
This is pretty fundamental. Here's the same thing with int and std::cout: http://codepad.org/N07Xckdy