I want to use polymorphism and create objects outside of main or any other function so that the functions are independent of the type of the objects I have. My code is as follows:
The main class:
class load{ //Main class
protected:
static load **L;
static int n, n1;
public:
load(){};
virtual float getpower()=0;
static int getn();
static load ** getL();
};
load **load::L;
int load::n;
int load::n1;
int load::getn(){
return n;
}
load** load::getL(){
return L;
}
The child class:
class load1:public load{
private:
float power;
public:
load1();
load1(int s);
void createUnits1();
float getpower();
}l1(0); //Object creation
load1::load1(int s){
createUnits1();
}
void load1::createUnits1(){
cout<<"Give the number of type 1 objects: "<<endl;
cin>>n1;
for (int i=0;i<n1;i++){
load1 temp; //Run default constructor
}
}
load1::load1(){
cout<<"Give the power of the device: "<<endl;
cin>>power;
n++;
if (n==1){
L=(load **)malloc(n*sizeof(load *));
}
else {
L=(load **)realloc(L,n*sizeof(load *));
}
L[n-1]=this;
}
float load1::getpower(){
return power;
}
The function of calculation:
float get_total_P(load **l, int num){
float tot_power=0;
for(int i=0;i<num;i++){
tot_power+=l[i]->getpower();
}
return tot_power;
}
My main function:
int main() {
load **l;
int num;
num=load::getn();
l=load::getL();
float total_P=get_total_P(l, num);
cout<<total_P;
return 0;
}
The upper code produces a segmentation fault but I can't see the reason why. The segmentation fault is on the line
tot_power+=l[i]->getpower();
So I guess my way of creating objects is wrong. Is there a better way to do this?
The reason for your segfault, is that l doesn't point to anything valid !
In main() you initialise l with load::getL(). But this function only returns the load::L which has the same type and was defined as static in your load class but was never initialized.
You have coded in your derived class load1 some initialisation code for L, but it is never invoqued in main().
Your code has also some severe design issues:
It's not advised to use malloc() and realloc() in C++ code. If you create an object in C++ use new. If you want some dynamic array, use vectors.
You could get L and hence l initialized if you'd create some load1 objects before calling getL(). But due to your realloc, l would then risk to point to an obsolete thus invalid address, if you would create any other load1 object before calling get_total().
It's bad practice and terrible design to request user input in a constructor. The constructor is meant to cosntruct an object with the parameters you give him when you call him. Imagine the user would give an invalid parameter ? The user would be asked for input whenever a load1 object is constucted. Even for temporary variables, not even speaking from the effect when you'd write load1 a[10];
Related
#include<iostream>
class Example{
int i=0,j=0;
public:
Example(){
std::cout<<"Default Constructor is called "<<j++<<std::endl;
}
~Example(){
std::cout<<"Destructor is Called "<<i++<<std::endl;
}
void display(){
std::cout<<"Display method called "<<std::endl;
}
};
void function(){
Example e;
e.display();
}
int main(){
function();
Example e1;
}
I'm trying to see how the constructor and destructor are called for two objects of the same class
The output I'm getting is
Default Constructor is called 0
Display method is called
Destructor is called 0
Default Constructor is called 0
Destructor is called 0
Why is my i and j variable not getting incremented
Your i and j variables are incremented, but the results are not printed.
You used postfix increment operator, so it is evaluated to the value before incrementing.
As you say, there are two objects, and they have independend member variables i and j because they are not static.
Since both the objects are independent of each other so incremented values will not affect another object. They are incrementing , if you want to see the incremented value then you can try pre-increment by using ++i or ++j instead of i++ or j++.
To know more you comment.
You have 2 different objects of class Example namely e and e1. Where e belongs to your defined function function, and e1 belongs to the main function.
So when you execute your program, object e only gets called once and the values of i and j get incremented for that object. But then you use another object e1, for which their values different than previously called object e. That's why values of i and j are different for different objects. Every time you create a new object, they get initialized to 0 for that object.
Now, what you have to do to make these values same for all objects is to make those variables static. Static will make variables accessible to all objects you create of same class with unchanged value and they don't get initialize every time you create a new object.
Here is how you can do it:
static int i,j;
But make sure you don't initialize static variables inside class. Otherwise program will throw an error. So, to initialize your static variables to 0, access them outside of class and set them to whatever value you wish to initialize them with. Like following:
int Example::i = 0;
int Example::j = 0;
That's it. Now you can achieve what you were looking for.
So now your code must look something like this:
class Example{
static int i,j;
public:
Example(){
std::cout<<"Default Constructor is called "<<j++<<std::endl;
}
~Example(){
std::cout<<"Destructor is Called "<<i++<<std::endl;
}
void display(){
std::cout<<"Display method called "<<std::endl;
}
};
int Example::i = 0;
int Example::j = 0;
void function(){
Example e;
e.display();
}
int main(){
function();
Example e1;
}
Change has been made. Please run this again
#include<iostream>
class Example{
static int i,j; //Changed
public:
Example(){
std::cout<<"Default Constructor is called "<<j++<<std::endl;
}
~Example(){
std::cout<<"Destructor is Called "<<i++<<std::endl;
}
void display(){
std::cout<<"Display method called "<<std::endl;
}
};
int Example::i = 0; //initializing i and j like this outside the class
int Example::j = 0; //Added
void function(){
Example e;
e.display();
}
int main(){
function();
Example e1;
}
Question : Declare a class named ‘StudentRec’ with three private members: ‘enrolNo’ of type int, ‘CGPA’ of type float and ‘branch’ of type string. Declare an array of objects named ‘Student’ of size 5 of class ‘StudentRec’. Write public member functions: (i) void sort (StudentRec Student[], int N ) to sort the data in ascending order with respect to ‘CGPA’ and (ii) void print (StudentRec Student[], int N ) to display the sorted and unsorted students’ records. Write main to test these member functions.
Doubt : The sorting part I will do later. My doubt is if in the below code(2nd last line ) Student[5].print(Student, N ); is correct way to call the function print? How else can this function be called via array of objects Also Student[0].print(Student, N ) gives correct output. Why ?
#include<iostream>
#include<cstring>
using namespace std;
class StudentRec
{
private:
int enrolNo;
float CGPA;
string branch;
public:
void assign()
{
cin>>enrolNo>>CGPA>>branch;
}
void sort (StudentRec Student[], int N );
void print(StudentRec Student[], int N )
{
int i;
for(i=0; i<5; i++)
{
cout<<"Student"<<" "<<i<<" " ;
cout<<Student[i].enrolNo<<" "<<Student[i].CGPA<<" "<<Student[i].branch<<endl;
}
}
};
int main()
{
StudentRec Student[5];
int i,N=5;
for(i=0; i<5; i++)
Student[i].assign();
Student[5].print(Student, N );
return 0;
}
As has been pointed out, Student[5].print(Student, N ); invokes undefined behavior as there is no Student[5]. However, your implementation of print doesn't actually use the object it is invoked on, so this is probably why this works in practice.
To give your program a somewhat reasonable design while keeping as close to the assignment as possible, you can declare the functions static:
static void print(StudentRec Student[], int N );
This means that, while the functions are declared inside the class and have access to private members of objects of the class, they don't rely on any concrete object to be invoked. You can then use them like this:
StudentRec::print(Student, N);
On a side note, your implementation of print doesn't actually use the parameter N.
I'm trying to writing some code for my c++ class. I'm using eclipse. I'm having a hard time trying to understand some of the instructions in the problem.
I've created a base class called Ship and then used inheritance for my CruiseShip class and CargoShip class.
For the CruiseShip class, I'm instructed to create
A print function that overrides the print function in the base class. The CruiseShip
class’s print function should display only the ship’s name and the maximum number
of passengers.
And similarly for the CargoShip class
A print function that overrides the print function in the base class. The CargoShip
class’s print function should display only the ship’s name and the ship’s cargo capacity.
I'm not sure what it means to "override" the print function in the base class.
It also instructs me to
Demonstrate the classes in a program that has an array of Ship pointers. The array
elements should be initialized with the addresses of dynamically allocated Ship ,
CruiseShip , and CargoShip objects. The program should then step through the array, calling
each object’s print function.
#include <iostream>
#include <string>
using namespace std;
class Ship
{
protected:
string ship_name;
int year_built;
public:
Ship()
{
ship_name="";
year_built=0;
}
void set_ship_name(string str)
{
ship_name=str;
}
void set_year(int y)
{
year_built=y;
}
int get_year()
{
return year_built;
}
string get_ship_name()
{
return ship_name;
}
void print(string, int)
{
cout<<"Ship name is "<<ship_name<<" and it was built in the year "<<year_built<<endl;
}
};
class CruiseShip: public Ship
{
private:
int max_passengers;
public:
CruiseShip()// :Ship(str,year)
{
max_passengers=0;
}
void set_passengers(int pass)
{
max_passengers=pass;
}
int get_passengers()
{
return max_passengers;
}
void print1(string, int)
{
cout<<"Ship name is "<<get_ship_name()<<" and max number of passengers are "<<max_passengers<<endl;
}
};
class CargoShip: public Ship
{
private:
int cargo_capacity_in_tons;
public:
CargoShip()//:Ship (str,year)
{
cargo_capacity_in_tons=0;
}
void set_capacity(int pass)
{
cargo_capacity_in_tons=pass;
}
int get_capacity()
{
return cargo_capacity_in_tons;
}
void print2(string, int)
{
cout<<"Ship name is "<<get_ship_name()<<" and its capacity is "<<cargo_capacity_in_tons<<" Tons."<<endl;
}
};
int main(){
CruiseShip ship1;
CargoShip ship2;
string ship_name1;
string ship_name2;
int year_built1;
int year_built2;
int max_passengers;
int cargo_capacity_in_tons;
cout<<"What is the name of the cruise ship?"<<endl;
cin>>ship_name1;
ship1.set_ship_name(ship_name1);
cout<<"What year was "<<ship_name1<<" built in?"<<endl;
cin>>year_built1;
ship1.set_year(year_built1);
cout<<"What is the maximum capacity of "<<ship_name1<<"?"<<endl;
cin>>max_passengers;
ship1.set_passengers(max_passengers);
//ship1.print(ship_name1, year_built1);
ship1.print1(ship_name1, max_passengers);
cout<<"What is the name of the cargo ship?"<<endl;
cin>>ship_name2;
ship2.set_ship_name(ship_name2);
cout<<"What year was "<<ship_name2<<" built in?"<<endl;
cin>>year_built2;
ship2.set_year(year_built2);
cout<<"What is the maximum capacity of "<<ship_name2<<" in tons?"<<endl;
cin>>cargo_capacity_in_tons;
ship2.set_capacity(cargo_capacity_in_tons);
ship2.print2(ship_name2, cargo_capacity_in_tons);
return 0;
}
Let´s say you have the following classes:
class Animal
{
private:
int x;
int y;
public:
virtual string sound() {return "Animal";}
void move() {x += 1; y+=1;}
};
class Cow
{
string sound() {return "Muh"} //this is overriding
string sound(string soundYouWant) {return soundYouWant;} //this is not overriding as string sound(string soundYouWant) is not the same as string sound()
void move() {x += 1; y+=1;} //this is also not overriding as move() in Animal has no virtual
};
So to summarize, overriding means you have a virtual method in the base class and you re-declare it in the derived class. This way, you are able to re-define it for every derived class (the method-body can be different for the base class and each of its derived classes).
Now to dynamic allocated arrays:
int size;
std::cin >> size;
int *array = new int[size]; //the array is stored on the heap
delete[] array; //deallocates the array and so frees the memory
If you create an array on the stack (without new), you either have to hardcode its size using literals (0, 1, 2, ...) or using a const int variableName. This way, the compiler knows the array size during compile time. So you have to know the array size while writing your program. Consequently, the compiler wouldn´t allow you to do this: std::cin >> size;.
Using new (dynamical arrays) you are allowed to specify the array size during compile time. So it is legal to let your program calculate the array size or take it as an user input. With dynamic arrays you also have a lot, lot, lot more memory than using the small stack (stackoverflow).
int *array: obviously the memory content is interpreted as integers. *array points to the first element of the array. int *array does NOT know the SIZE of the array. You have to keep track of that yourself.
new int[size]: You are reserving space for size * integers on the heap.
You might know that C++ does not have a garbage collector. This is when delete[] array; comes into play. When you don´t need array anymore (this includes other pointers pointing to array) you should call delete to free the memory. With small, short running programs, forgetting it won´t matter as the OS (operation system) will free the memory after your program has terminated. Nevertheless, you should use delete as not using it is very bad still and will lead to trouble with bigger programs. You should place delete in the destructor of a class (~clasname()) if you use array within a class.
I'm trying to make a chess program, but I want to be able to implement different AIs in it. Thus I made a abstract AIgeneric class and the derived class AIrandom off of AIgeneric. Then in my chessAI interface, I create a list of the the AIs, and try to call their getNextMove function and run into a segfault. The code is as below:
class AIgeneric {
public:
virtual int getNextMove(int*, const int &) = 0;
}
class AIrandom : public AIgeneric {
public:
AIrandom();
virtual int getNextMove(int*, const int &);
}
class chessAI {
public:
chessAI();
~chessAI();
void setAI();
int getNextMove(int*, const int &);
private:
vector<AIgeneric*> AIlist;
vector<string> names;
int selectedAI;
};
chessAI::chessAI () {
AIrandom randomAI;
AIlist.push_back(&randomAI);
names.push_back("Random AI");
selectedAI = -1;
}
int chessAI::getNextMove(int * board, const int & color) {
return AIlist[selectedAI]->getNextMove(board, color); //segfault on this line
}
It'd be great if anyone could help me on this problem!
Edit: I do set selectedAI to 0 before calling getNextMove.
In this code:
chessAI::chessAI () {
AIrandom randomAI;
AIlist.push_back(&randomAI);
names.push_back("Random AI");
selectedAI = -1;
}
You store a pointer to a local variable into your vector. After the constructor returns that pointer is no longer valid.
Remember that all local variables are stored on the stack, and the stack is reused in other functions. So when you use the pointer in the vector, it now points to some other functions memory and not the one object you declared.
This can be solved in three ways:
Allocate the object on the heap:
AIlist.push_back(new AIRandom);
Not using pointers at all.
Use smart pointers, such as std::unique_ptr.
You call selectedAI = -1; and then AIlist[selectedAI]->.... What do you expect AIlist[-1] to be, other than undefined behavior?
I expect this is because AIlist[selectedAI] is out of bounds. You can confirm this by replacing it with AIlist.at(selectedAI). Keep in mind that this index is -1 immediately after the constructor...
My question is how to access and modify a 2D array defined in one class that is friends with another class. Below are some details on my question:
In class A I declare and allocate the appropriate space for my 2D array (pointer-to-pointer) u.
Class A
{
public:
friend class B;
long double **u;
int fun;
void make();
};
void A::make()
{
long double **u = new long double *[nx];
for (int i=0;i<nx;i++)
u[i] = new long double [ny];
int fun = 9;
}
Class A is friends with Class B; I need to use the array I declared in Class A in a function defined in class B. Below is my Class B:
class B
{
public:
void get(A*);
};
void B::get(A *pt)
{
using namespace std;
cout << pt->fun;
cout << pt->u[0][0];
}
I get a Bus error on my second cout pt->u[0][0]. Is there a simple way to use this setup I have to access my u[][] array? I think that I get the error because the pointer points to the 1st entry of my array, thus my whole 2D array is saved in memory as a single row (thinking aloud here). I'm a Fortran guy so this stuff is a little new to me.
Any help or "pointers" to other helpful threads would be appreciated.
Thank you !
Alberto
I think you get error because A::u is not initialized ( in method A::make you initialize a local variable u, not member. You need to change
void A::make()
{
long double **u = new long double *[nx]; // should be just u, or this->u.
There are some problems with your code: nx and ny don't seem to be defined anywhere, and in make you don't initialize A::fun at all, you instead set a local variable named fun which goes out of scope immediately.
As for your error, it sounds like the error stems from the fact that make() has not been called on pt. Ensure that make() is called on the instance you pass to get, otherwise the array u will not be allocated.