C++: Why do these functions use different copies of the vector? - c++

I have the problem of class functions making changes on different copies of a vector rather than the one saved in an instance of the corresponding object.
Description of the Main function:
This is the main function. It first creates an object Menno of class Mats, which is initialized with its constructor and has a private vector of type int named F full of values -1. It then is used to create an object of class Calculator named Calli. The object Menno is saved in a private object variable of type Mats named Matrices in Calli. Finally, Matrices is returned by the getMatrices() function of Calli and printF() is carried out on this object variable, which changes values in F and is supposed to change F for all time.
Problem:
As can be seen after executing the program, the changes made by printF() and setf() do not get saved in the object variable Matrices. This leads me to think that the initialization of F in the constructor works well, but the functions then use other copies of this vector rather than the saved one.
Background:
As a Java Coder, I was advised to use pointers for most cases, but I still can't understand why this code doesn't work as intended. I recently investigated C++ as a programming language, went through thenewbostons video guide and printed out syntax lists but they don't help me here. Any explanation is appreciated!
// main function
#include "Calculator.h"
#include "Mats.h"
#include <iostream>
#include <vector>
using namespace std;
int main()
{
int N = 4;
Mats Menno(N);
Calculator Calli(Menno);
Calli.getMatrices().printF();
Calli.getMatrices().setf(2,1);
Calli.getMatrices().printF();
}
// Calculator header
#ifndef CALCULATOR_H
#define CALCULATOR_H
#include "Mats.h"
#include <vector>
class Calculator
{
public:
Calculator(Mats M);
Mats getMatrices();
protected:
private:
Mats Matrices;
};
#endif // CALCULATOR_H
// Calculator cpp
#include "Calculator.h"
#include "Mats.h"
#include <iostream>
#include <vector>
using namespace std;
Calculator::Calculator(Mats M)
: Matrices(M)
{
}
Mats Calculator::getMatrices(){
return Matrices;
}
// Mats header
#ifndef MATS_H
#define MATS_H
#include "Calculator.h"
#include <vector>
class Mats
{
public:
Mats(int N);
int getf(int i);
void setf(int i, int fh);
std::vector<int> getF();
void printF();
protected:
private:
std::vector<int> F;
};
#endif // MATS_H
// Mats cpp
#include "Calculator.h"
#include "Mats.h"
#include <iostream>
#include <vector>
using namespace std;
Mats::Mats(int N)
{
std::vector<int> Fh;
F = Fh;
F.resize(N);
for (int i = 0;i<N;i++){
F[i] = -1;
}
}
int Mats::getf(int i){
return F[i];
}
void Mats::setf(int i, int fh){
F[i] = fh;
}
std::vector<int> Mats::getF(){
return F;
}
void Mats::printF(){
F[1] = 300;
cout << "F: " << endl;
for (int i = 0; i<F.size(); i++) {
cout << F[i] << " ";
}
cout << endl;
F[1] = 200;
}

Because
Mats getMatrices();
returns a copy of the class member. Change it to return it by reference:
Mats &getMatrices();
Note that returning a class member by reference has certain ramifications that you need to understand. You will find all the details in your favorite C++ book.
What happened here is that your self-described background in Java is getting in the way. C++ classes work fundamentally different than Java's classes. You need to forget everything you know about classes, as you know them in Java, and focus on learning how C++ classes work, from the basics.

Related

How to declare a <vector> object and use push_back inside a class?

I'm trying to build a class named "Tombola" which should contain as private variable an empty vector. This should be filled at runtime through the class member Tombola.estrai(), which generates a random number and insert it inside the vector named "order" by the method order.push_back(number). This is the class definition in the tombola.h header:
#ifndef TOMBOLA_H
#define TOMBOLA_H
#include <cstdlib>
#include <vector>
using namespace std;
class Tombola {
private:
bool on_off[90];
int tabellone[9][10];
int x_max = 9;
int y_max = 10;
vector<int> order;
public:
Tombola();
~Tombola();
void nuovo();
int estrai();
bool completato();
void stampa();
void stampa_tab();
};
#endif
And this is the implementation of constructor/destructor and Tombola::estrai() inside tombola.cc:
#include "tombola.h"
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <vector>
#include <iostream>
using namespace std;
Tombola::Tombola () {
vector<int> ord;
order = ord;
int z=1;
for(int i=0;i<90;i++) {
on_off[i] = false;
}
for(int j=0;j<=x_max;j++) {
for (int k=0;k<=y_max;k++) {
tabellone[j][k] = z;
z++;
}
}
}
Tombola::~Tombola() {
cout << "Tombola is destroyed" << endl;
}
int Tombola::estrai() {
srand(time(NULL));
int estrazione = int(ceil(rand()/double(RAND_MAX)*90));
on_off[estrazione]==true;
order.push_back(estrazione);
return order.back();
}
and this is the call to the method in the main.cpp file:
#include "tombola.h"
#include <cstdlib>
#include <iostream>
#include <vector>
#include <ctime>
using namespace std;
int main () {
Tombola natale;
cout << natale.estrai();
}
When I compile the program everything goes fine, but when I execute the main I get a segmentation fault error which seems to be due to some sort of allocation error when trying to store the item inside the order vector, as reported by the debugger. Could someone explain to me how to solve the error and why the error occours? Thank you.
The reason of segmentation fault is in the constructor. You have to change for(int j=0;j<=x_max;j++) to for(int j=0;j<x_max;j++) in order not to cross the bounds of the array.
for(int j=0;j<x_max;j++) {
for (int k=0;k<y_max;k++) {
tabellone[j][k] = z;
z++;
}
}
However, there are also some minor issues in the code that are worth being mentioned
declaring default-initialized ord vector and assigning it to order is pointless because order is already default-initialized.(See member initializer list for more information).
using namespace std; in a header file is a terrible idea, because if you had a large codebase, and had multiple source files where you want to include that header, everywhere the using statement will be applied, which probably is not desired.

Class don't work in c++ project when created in other files

I made a class in a .cpp and a .h file with in the same project, and then I tried to make a calculating code. I made an object for it, with the name "co". I then tried to build it and run the file, and it showed nothing. Why is that happening and how can I try to fix it?
The code:
main.cpp
#include <iostream>
#include <fstream>
#include <string>
#include "CalculatorClass.h"
using namespace std;
int main()
{
calculatorClass co ();
}
calculatorClass.cpp
#include "calculatorClass.h"
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
calculatorClass :: calculatorClass ()
{
int x = 25;
int y = 37;
int z = 51;
int a = 14;
int b = 63;
int c = 75;
cout << x * y * z * a * b * c ;
}
calculatorClass.h
#ifndef CALCULATORCLASS_H
#define CALCULATORCLASS_H
class calculatorClass
{
public:
calculatorClass (int hello);
calculatorClass();
protected:
private:
};
#endif // CALCULATORCLASS_H
Thanks!
change calculatorClass co (); to calculatorClass co. This will work. The explanation is as the following question - C++: warning: C4930: prototyped function not called (was a variable definition intended?).
By calling calculatorClass co (); you are not creating an object; you are declaring a function.
It looks like you are trying to create a constructor.
So the first thing to do is look at your calculatorClass.h. You need to change it to look like this because a constructor is a member function that has the same name as the class.
#ifndef CALCULATORCLASS_H
#define CALCULATORCLASS_H
class calculatorClass
{
public:
calculatorClass(); //Constructor.
protected:
private:
};
#endif // CALCULATORCLASS_H
Then in your calculatorClass.cpp you will need to change it to this.The function header of a constructor's external definitions takes a form like this:
Classname::Classname(Parameters)
#include "calculatorClass.h"
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
calculatorClass::calculatorClass() // Changed.
{
int x = 25;
int y = 37;
int z = 51;
int a = 14;
int b = 63;
int c = 75;
cout << x * y * z * a * b * c;
}
Then in your main.cpp file you are going to define an instance of the class calculatorClass which I did and named it calc. Now, the function calculatorClass is automatically called in main().
#include <iostream>
#include <fstream>
#include <string>
#include "CalculatorClass.h"
using namespace std;
int main()
{
calculatorClass Calc; // Define a calculatorClass object
return 0;
}
Just a heads up, when you use ints they only hold 32 bits. So with all these large numbers you are trying to multiplying will roll over to a large negative value and you will not get the correct answer.
You might want to use long long int.
The main issue in the code, that the following line is interpreted differently than you think:
calculatorClass calc();
This line is interpreted as a declaration of a function prototype instead of creating a new object of calculatorClass. This is known as the most vexing parse as noted in the comments.
There is a way to declare and initialize an object in a similar fashion:
calculatorClass calc{};
Notice that I have used {} and not () ! This was introduced in order to avoid this vexing parsing of the code.
In addition, I want to comment about some other bad habits in the code:
Using using namespace std; is a bad habit, which causes name pollution and may cause bugs with name ambiguity, and in the worst case related to unexpected functions being called!
Class names always start with a capital letter - calculatorClass should be Calculator (we know that it is a class, thus class shouldn't appear in the name!).
There is no need in the protected and private modifiers here.

Invalid use of non static data member C++

Here is my code
main.cpp
#include <iostream>
#include "header.h"
#include "source.cpp"
using namespace std;
int main()
{
cout << "Hello world!" << endl;
int testarray[]={1,3,5,7};
mymatrix* first=new mymatrix(testarray,2,2);
return 0;
}
and header.h
using namespace std;
#include <iostream>
#include <string>
class mymatrix{
public:
int i;
int j;
int marray[];
mymatrix(int m[],int rows,int cols ) : marray(m),i(rows),j(cols)
{
cout<<"this is for testings ";
}
mymatrix()
{};
~mymatrix(){
// delete[] marray;
};
};
I get this error :Invalid use of non static data member mymatrix::i
what I wanna do is make a object of my
matrix class and pass an array
Convert it from
int marray[];
to
int *marray;
In addition, either use C paradigm or use C++ one but not the mixture.
Instead of
mymatrix* first=new mymatrix(testarray,2,2);
use
mymatrix first(testarray,2,2);
Let the compiler allocate and release the memory instead of you.
If you have no restriction about the C++ libraries that you use, consider std::vector library to manage your dynamic arrays.
Instad of managing memory out of the object, manage it inside the object specially inside constructor and destructor.

Data "member not declared in this scope"

I'm trying to create a vector which will store objects. I have added to the header file of the class as a private data member.
I am trying to initialize this vector as being empty (so that I can add objects to it later on in the program) but when I compile this program to test, this error is returned:
...error: '_bookingVector' was not declared in this scope|
I think the problem is with my initialization list on my default constructor(_bookingVector is obviously the vector):
Schedule::Schedule() : _bookingVector()
{ }
Is my syntax wrong? Or are vectors initialized differently?
Here is my code:
Schedule.h
#ifndef SCHEDULE_H
#define SCHEDULE_H
#include "Booking.h"
#include <vector>
using namespace std;
class Schedule
{
public:
Schedule();
void AddBooking(int bday, int btime, int btrainer, int bid);
void RemoveBooking(int bday, int btime);
void DisplaySchedule();
void DisplayAvailableTimeSlots();
//For Testing
void DisplayDebug();
private:
vector<Booking> _bookingVector;
};
#endif // SCHEDULE_H
Schedule.cpp
#include "Schedule.h"
#include "Booking.h"
#include <vector>
#include <iostream>
Schedule::Schedule() : _bookingVector()
{ }
void AddBooking(int bday, int btime, int btrainer, int bid){
Booking bookingObject(bday, btime, btrainer, bid);
_bookingVector.push_back(bookingObject);
}
void DisplayDebug(){
for(int i = 0; i < _bookingVector.size(); ++i){
cout << _bookingVecotr[i] << endl;
}
}
I'm very eager to learn what I'm doing wrong and fix it.
The issue is not with the constructor, which looks fine if unnecessary1. The issue is that you have defined AddBooking and DisplayDebug as non-member functions, but these should be members in order to access other members of the class.
Modify the definitions to be in the scope of the Schedule class thus:
void Schedule::AddBooking(int bday, int btime, int btrainer, int bid) { ...
^^^^^^^^^^
void Schedule::DisplayDebug(){ ...
^^^^^^^^^^
Also, don't say using namespace std in a header file (I'd go further and say don't say it anywhere but there isn't universal agreement on that.)
1 Your default constructor does not do anything that the compiler-generated one wouldn't do. You can safely remove it.

Initializing vector inside constructor giving seg fault

I have a card class in which I initialize a vector:
#ifndef CARD_H
#define CARD_H
#include <vector>
using namespace std;
class Card
{
private:
vector<int> CC;
vector<int> iChance;
public:
Card();
void draw_Card();
};
#endif
And in my .cpp file I have
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <vector>
#include <algorithm>
#include <iterator>
#include "card.h"
using namespace std;
Card::Card()
{
srand(time(NULL));
vector<bool> drawn(20);
for (int i = 0; i < 20; i++)
{
int numvalue = rand()%20 + 1;
if (drawn[numvalue - 1])
{
i--;
continue;
}
else
{
drawn[numvalue - 1] = true;
CC.push_back(numvalue);
iChance.push_back(numvalue);
}
}
copy (CC.begin(), CC.end(), ostream_iterator<int>(cout, " "));
}
It is segfaulting when I call the push_back function for CC, which means the vector CC is not being passed in correctly?
If i called the vectors not in the private area and directly inside the constructor it works. Sorry if this maybe a really simple fix, just started learning classes and vectors. Thank you for the help.
Edit: I am almost certain this is the problem. The value of CC and iChance are not getting past into the constructor, so when the program tries to set a value to the variables nothing exists and it seg faults.
Also I noticed that if i instead declared the CC and iChance variable in the cpp file and not the .h file the program would work.
I am just trying to figure out why and how I could fix this