(C++) Invalid value when accessing variable from another class - c++

Whenever I try to access time_series_length from the Example class I get an invalid number.
class Indicator
{
public:
Indicator(){};
Indicator(std::vector<DayData> data, int days) // days = 30 from the main function
{
time_series = data;
time_series_length = days;
std::cout << time_series_length << std::endl; // PRINTS OUT (30) in the console
};
// Returns the length in days of the time series
int get_ts_length()
{
return time_series_length;
}
// Returns the time series in a vector of DatData structs
protected:
int time_series_length; // the length of the time_series in days
std::vector<DayData> time_series;
};
class Example : public Indicator
{
public:
Example(){};
void check()
{
std::cout << Indicator::time_series_length; // PRINTS OUT (-349926832) in the console
}
};
struct DayData
{
double adj_close;
int volume;
};
int main()
{
const int days = 30;
// ... I populate data with DayData structs
Indicator(data, days);
Example a;
a.check();
return 0;
}
I should get output
30
30
,instead I get
30
-349926832

You did not assign anyting to the created instance of the Example object a. It was only initialized. It dedicated a piece of memory to your class, but did not put anything in there, it's a random value in memory.

Initialization is missing for the Indicator class, which is part of "Example a;"
You have to call Indicator initialization with object -> a; so you call respective method -> get_ts_length() instead data member as good coding practice.

Related

global function and class reference

I want to send integer value in class to global function from main. How should I send it as a parameter,I am sending the parameters wrong
Tetris
{
private:
int num;
}
printBoard(Tetris &t);
int main()
{
Tetris tetris;
printBoard(board,tetris);
}
i want to send num , to printboard.
There are several problems with the shown code.
First, you're missing the class keyword when defining the class.
Second, the return type of the function is also missing.
Third, the function has only one parameter but you're passing two arguments.
i want to send num , to printboard
You can add a getter called getNum which you can use from inside your free function as shown below:
vvvvv------------->added this class keyword
class Tetris
{
private:
int num = 0; //don't forget to initialize
public:
//add a getter
int getNum() const
{
return num; //return a copy
}
};
vvvv----------------------->added return type as void
void printBoard(Tetris &t)
{
std::cout << t.getNum(); //use the getter
}
int main()
{
Tetris tetris;
printBoard(tetris);
}
Demo

Array of pointers to objects and inherited objects

I am trying to make a program which creates an array of pointers to objects, including inherited objects.
The error I'm getting is on the first bracket ( of the cSClass eg SArray[2] = new cSClass(...); (Last line at the bottom of all the code). The error says "no instance of constructor cSClass::cSClass matches the argument list"
Thank you
All the code is below:
The code for the header of the superclass is:
class sClass;
class sClass {
protected:
std::string name;
int yearBuilt;
public:
// Constructor
sClass(string n = "s1", int yb = 2000) {
name = n;
yearBuilt = yb;
}
// Mutator functions
void setName(string);
void setYearBuilt(int);
// Accessor functions
string getName() {
return name;
}
int getYearBuilt() {
return yearBuilt;
}
// Functions
void getInfo();
};
main class of the superclass:
#include "sClass.h"
using namespace std;
// Mutators
void sClass::setName(string n) {
name = n;
}
void sClass::setYearBuilt(int yb) {
yearBuilt = yb;
}
// Print function
void sClass::getInfo() {
cout << "Name: " << name << endl;
cout << "Year Built: " << yearBuilt << endl;
}
Code for the subclass header:
#include "sClass.h"
class cSClass : public sClass {
protected:
int maxPassengers;
public:
// Constructor
cSClass(int mp = 2000) : sClass() {
maxPassengers = mp;
}
// Mutator functions
void setMaxPassengers(int);
// Accessor functions
int getMaxPassengers() {
return maxPassengers;
}
// Functions
void getInfo() {
}
};
Code for the subclass class:
#include "cSClass.h"
// Mutators
void cSClass::setMaxPassengers(int mp) {
maxPassengers = mp;
}
// Print function
void cSClass::getInfo() {
cout << "Name: " << name << endl;
cout << "Maximum Passengers: " << maxPassengers << endl;
}
And lastly this is the main program code in which i am getting errors where i am trying to fill the array:
#include "sClass.h"
#include "cSClass.h"
int main() {
sClass *SArray[6];
SArray[0] = new sClass(...);
SArray[1] = new sClass(...);
SArray[2] = new cSClass(...);
SArray[3] = new cSClass(...);
}
Edit: Error is at the top, and the arguments I'm passing are
SArray[2] = new cSClass("RMS Queen Mary 2", 2003, 2700);
The constructor needed for this to work is missing:
SArray[2] = new cSClass("RMS Queen Mary 2", 2003, 2700);
It could look like this
class cSClass : public sClass {
cSClass(const std::string& name, int yb, int mp) :
sClass(name, yb),
maxPassengers{mp}
{}
//...
}
You also have some other problems:
You have a non-virtual destructor in the base class. When you delete your objects through a non-virtual base class pointer, only the base class destructor will be called. To fix that, add this to sClass:
virtual ~sClass() = default;
Two definitions of cSClass::getInfo(). Settle for only declaring the function in the class definition and leave the definition of the member function in the .cpp file as-is.
Memory leaks since you don't delete what you've newed. To avoid that problem, it's better to use smart pointers that will delete the object when it goes out of scope, like it will in case an exception is thrown (that you catch). Example:
#include <memory>
//...
std::unique_ptr<sClass> SArray[6]; // or std::array<std::unique_ptr<sClass>, 6> sArray;
SArray[2] = std::make_unique<sClass>();
SArray[2] = std::make_unique<cSClass>("RMS Queen Mary 2", 2003, 2700);
Note: If you instead want a dynamic amount of sClass pointers, use a std::vector:
#include <vector>
//...
std::vector<std::unique_ptr<sClass>> SArray;
SArray.push_back(std::make_unique<sClass>());
SArray.push_back(std::make_unique<sClass>());
SArray.push_back(std::make_unique<cSClass>("RMS Queen Mary 2", 2003, 2700));
SArray.push_back(std::make_unique<cSClass>("RMS Queen Mary 2", 2003, 2700));
There are two fundamental errors in your code!
First, you have provided two definitions for the getInfo member function of the cSClass. If you want to keep the second (out-of-body) definition, then you need to remove the definition part of the (in-body) declaration. So, replace:
// Functions
void getInfo() { /// Note: adding the { } provides a function DEFINITION
}
with this:
// Functions
void getInfo(); // No body provided, so it's JUST a declaration (defined elsewhere)
Then, the calls you make to your constructors cannot have the ... in the argument list (though I'm not sure what you are trying to achieve with this). Simply provide empty argument lists:
SArray[0] = new sClass();
SArray[1] = new sClass();
SArray[2] = new cSClass();
SArray[3] = new cSClass();
or, as there is no argument, you can invoke the 'default' constructor by omitting the argument lists completely:
SArray[0] = new sClass;
SArray[1] = new sClass;
SArray[2] = new cSClass;
SArray[3] = new cSClass;
Also, for completeness, remember to free the memory for the objects you created with new, when you're done with them:
delete SArray[0];
delete SArray[1];
delete SArray[2];
delete SArray[3];
Feel free to ask for further clarification and/or explanation.

Using an object inside of a class and using the other class' object's methods isn't working

I'm trying to make a clock object by simply making an object called "boundedCounter" which has a value and a limit, the value starts at 0 and keep counting up until it reaches the limit, then it resets to 0 and continues counting. I want to have the clock object use 3 bounded counters for each seconds, minutes and hours and the rest is simple. When I did it in java, it worked pretty good. But now after learning C++, I can't seem to find why making the boundedCounter object inside of the clock class isn't working. I tried making it an inherited class, making methods and such. Here's the code:
class boundedCounter {
private:
int value, limit;
public:
boundedCounter(int boundLimit) {
value = 0;
limit = boundLimit;
}
void next() {
if (++value == limit) {
value = 0;
}
}
void setLimit(int boundLimit) {
limit = boundLimit;
}
int getValue() {
return value;
}
};
class Clock : private boundedCounter {
public:
boundedCounter seconds(60);
boundedCounter minutes(60);
boundedCounter hours(24);
seconds.setLimit(60);
};
Errors:
E0079 expected a type specifier line 35
E0079 expected a type specifier line 36
E0079 expected a type specifier line 37
E0077 this declaration has no storage class or type specifier line 39
E0065 expected a ';'
There are several problems in this code; First of all, there is not need to inherent from the other class! Inheritance is defined as "is a" relation. Clock isn't a bounded counter, it has 3 different counters - seconds, minutes, hours (thus, we have a "has a" relation). Therefore, you should change the relation to composition. As a rule of thumb - you should prefer composition over inheritance.
Secondly, you cannot initialize non-static member variables like that, that must be done inside non-static function (and most likely in the ctor of the class). Notice that I have put it in the initializer list, and not in the body of the ctor, which is the best practice.
The following code does compile properly:
class boundedCounter {
private:
int value, limit;
public:
boundedCounter(int boundLimit) {
value = 0;
limit = boundLimit;
}
void next() {
if (++value == limit) {
value = 0;
}
}
void setLimit(int boundLimit) {
limit = boundLimit;
}
int getValue() {
return value;
}
};
class Clock {
public:
boundedCounter seconds;
boundedCounter minutes;
boundedCounter hours;
Clock() :
seconds(60),
minutes(60),
hours(24)
{
}
};
The compiler expected in this case you declare the boundedCounter objects in class Clock following the syntax below:
boundedCounter seconds = 60;
boundedCounter minutes =60;
boundedCounter hours = 24;
The line 'seconds.setLimit(60)' won't work because it is an attempt to execution of seconds' function member on class declaration.
Furthermore, when you declare 'class Clock : private boundedCounter', you create a extended bounderCounter called Clock with the private function members next, setLimit and getValue. I'm sure it is not what you want from the class Clock to be.
Below you can check your code:
class boundedCounter {
private:
int value = 0;
int limit;
public:
boundedCounter(int boundLimit) : limit(boundLimit) {}
void next() {
if (++value == limit)
value = 0;
}
void setLimit(int boundLimit) { limit = boundLimit; }
int getValue() { return value; }
};
struct Clock {
boundedCounter seconds = 60;
boundedCounter minutes = 60;
boundedCounter hours = 24;
};

Why is this program of hybrid inheritance giving wrong output?

In this program, I am trying to inculcate hybrid inheritance in this program but this is giving wrong output. I have taken arithmetic as base class and add,sub,mul,div as its derived classes.
And then I have derived a class result using add,sub,mul,div as base classes. I have tried all the data types but with all it gives wrong or zero output.
#include "iostream"
using namespace std;
class arithmetic
{
public:
float var1,var2;
void introduce()
{
cout<<"This program will perform arithmetic on two variables"<<endl
<<"Enter the first variable: ";
cin>>var1;
cout<<"Enter the second variable: ";
cin>>var2;
}
};
class add:public arithmetic
{
protected:
float res_add;
public:
void show_add()
{
res_add=var1+var2;
cout<<"Addition of those variables gives "<<res_add<<endl;
}
};
class sub:public arithmetic
{
protected:
float res_sub;
public:
void show_sub()
{
res_sub=var1-var2;
cout<<"Subtraction of those variables gives "<<res_sub<<endl;
}
};
class mul:public arithmetic
{
protected:
float res_mul;
public:
void show_mul()
{
res_mul=var1*var2;
cout<<"Multiplication of those variables gives "<<res_mul<<endl;
}
};
class div:public arithmetic
{
protected:
float res_div;
public:
void show_div()
{
res_div=var1/var2;
cout<<"Divison of those variables gives "<<res_div<<endl;
}
};
class result:public add, public sub,public mul,public div
{
public:
void showres()
{
cout<<"Arithmetic on the given two varibales gives us the following result:"<<endl;
}
};
int main()
{
result example;
arithmetic var;
var.introduce();
example.showres();
example.show_add();
example.show_sub();
example.show_mul();
example.show_div();
return 0;
}
You are creating two separate object var (base class object) and example ( derived class object). Initializing the var1 and var2 by calling the var.introduce() and calling the methods show_add(), show_sub() etc. in the example object, in example object var1 and var2 is not initialized. so whatever arithmetic operation you are calling is getting applied in the uninitialized var1 and var2 member variable of example object.
you don't need to create the base class object(var). call the intruduce() method from the example then it will start working fine.
Please go through the below sample code to understand the concept of virtual base class.
#include <iostream>
class A
{
public:
int i;
};
class B : virtual public A
{
public:
int j;
};
class C: virtual public A
{
public:
int k;
};
class D: public B, public C
{
public:
int sum;
};
int main()
{
D ob;
ob.i = 10; //unambiguous since only one copy of i is inherited.
ob.j = 20;
ob.k = 30;
ob.sum = ob.i + ob.j + ob.k;
std::cout << "Value of i is : "<< ob.i<<"\n";
std::cout << "Value of j is : "<< ob.j<<"\n";
std::cout << "Value of k is : "<< ob.k<<"\n";
std::cout << "Sum is : "<< ob.sum <<"\n";
return 0;
}
Output:
Value of i is : 10
Value of j is : 20
Value of k is : 30
Sum is : 60
Live Demo on coliru
If you want to avoid virtual inheritance and want something simpler, use composition.
For this, class result should contain objects of add, sub, mul and div.
The resulting code for result will look something like this:
class result:public arithmetic
{
public:
mul m;
add a;
sub s;
div d;
void assignvals()
{
m.var1 = var1; m.var2 = var2;
a.var1 = var1; a.var2 = var2;
s.var1 = var1; s.var2 = var2;
d.var1 = var1; d.var2 = var2;
}
void showres()
{
cout<<"Arithmetic on the given two variables gives us the following result:"<<endl;
}
};
The resulting code for main will look something like this:
int main()
{
result example;
example.introduce();
example.assignvals();
example.showres();
example.a.show_add();
example.s.show_sub();
example.m.show_mul();
example.d.show_div();
return 0;
}
Note: Some compilers will complain if div is used as a class name because it is also the name of a library function in C++. So you will have to change the name of this class.

C++ Class isn't returning the correct value of my private variable

Im trying to get this program to take the users input and put that into a public function and assign it to the privateVariable, then I want it to return the value of privateVariable to main() and output it to the screen, but all it displays is the value of an undefined int ( -858993460 ). What logical problem am I having here ?
#include <iostream>
#include <string>
using namespace std;
class MyClass
{
private:
int privateVariable;
public:
int userVariable;
void setVariable(int userVariable)
{
privateVariable = userVariable;
}
int getVariable()
{
return privateVariable;
}
};
int main()
{
int userVariable;
cin >> userVariable;
MyClass object1;
MyClass object2;
object1.setVariable(userVariable);
object2.getVariable();
cout << object2.getVariable();
system("PAUSE");
return 0;
}
You are setting in object1 and getting from object2. object1 and object2 are different objects. As variable in object2 is not set, you get a garbage value.
And I see no use of public userVariable in MyClass.
You are not setting the variable. You call setVariable on object1 and getVariable on object2, so the member of object1 remains uninitialized.
object1.setVariable(5); // object1.privateVariable = 5
// object2.privateVariable -> still uninitialized
object2.getVariable(); // returns uninitialized variable
For this to work, depending on what you want:
class MyClass
{
private:
static int privateVariable;
//......
}
This way, privateVariable will be a class-scoped member, not instance-scoped. That means it has the same value for all instances of the class (and even if instances were not created). This also means you can make both your functions static:
class MyClass
{
private:
static int privateVariable;
public:
static void setVariable(int userVariable)
{
privateVariable = userVariable;
}
static int getVariable()
{
return privateVariable;
}
};
and you can call the methods without instances:
MyClass::setVariable(5); //MyClass.privateVariable = 5;
MyClass::getVariable(); //returns 5
object1.getVariable(); //returns also 5
Another option is, if you don't want static members, to set the member for both objects:
object1.setVariable(5); // object1.privateVariable = 5
// object2.privateVariable -> still uninitialized
object2.setVariable(5); //object2.privateVariable = 5
object2.getVariable(); // returns 5
Or, you could define a constructor and set the variable there:
class MyClass
{
private:
static int privateVariable;
//......
public:
MyClass()
{
privateVariable = 5;
}
}
With this, every object you create will have the member initialized to 5.
object2 does not have your variable initialized as you set it on object1, the code you posted would only work if privateVariable was static.