structure name not declared and swap function swaps without pass by refrence - c++

I have this code,which takes input of 3 students from division a and b each.
those 2 divions are sorted and merged in a 3rd array according to birth dates of students.
the swap function ,I have not passed anything by refrence still its swapping and sort output is correct !!!.
NOTE:the line below #include..
void swap(struct a,struct b)
it should be
void swap(struct student a,struct student b)
but without changing that the program is runnong and giving correct outputs !! how ??
#include<iostream>
#include<string.h>
using namespace std;
void swap(struct a,struct b);
void findweek(struct student ar[10],int l,int bd1,int bm1);
struct student
{
//m is for month and b is for birthdate prn=prn number,name=name of student
int m,bd;
char prn[10],name[10];
};
int main()
{
//2 divisions a and b declared and will be merged into c
struct student a[3], b[3], c[6];
//division a input
for(int i=0;i<3;i++)
{
cout<<" Enter name of student "<<endl;
cin>>a[i].name;
cout<<"Enter prn no. "<<endl;
cin>>a[i].prn;
cout<<"Enter birth day "<<endl;
cin>>a[i].bd;
cout<<"Enter birth month "<<endl;
cin>>a[i].m;
}
//sorting of a
for(int i=0;i<3;i++)
{
for(int j=i;j<3;j++)
{
if(a[i].m>a[j].m)
{
swap(a[i],a[j]);
}
else if(a[i].m==a[j].m)
{
if(a[i].bd>a[j].bd)
{
swap(a[i],a[j]);
}
}
}
}
//division b input
for(int i=0;i<3;i++)
{
cout<<" Enter name of student "<<endl;
cin>>b[i].name;
cout<<"Enter prn no. "<<endl;
cin>>b[i].prn;
cout<<"Enter birth day "<<endl;
cin>>b[i].bd;
cout<<"Enter birth month "<<endl;
cin>>b[i].m;
}
//sorting of b
for(int i=0;i<3;i++)
{
for(int j=i;j<3;j++)
{
if(b[i].m>b[j].m)
{
swap(b[i],b[j]);
}
else if(b[i].m==b[j].m)
{
if(b[i].bd>b[j].bd)
{
swap(b[i],b[j]);
}
}
}
}
cout<<"-----------------------"<<endl;
cout<<"Division A"<<endl;
int count=0;
for(int i=0;i<3;i++)
{ //c has merged array , a being filled first
c[i]=a[i];
count++;
cout <<c[i].name<<"\t"<<c[i].prn<<"\t"<<c[i].bd<<"|"<<c[i].m<<endl;
}
cout<<"Division B"<<endl;
for(int i=0;i<3;i++)
{
//resume filling the array from count
c[count]=b[i];
cout <<c[count].name<<"\t"<<c[count].prn<<"\t"<<c[count].bd<<"|"<<c[count].m<<endl;
count++;
}
int bd1,bm1;
cout<<"Enter date to find birthdays in that week "<<endl;
cin>>bd1;
cout<<"Enter corresponding month "<<endl;
cin>>bm1;
findweek(c,count,bd1,bm1);
return 0;
}
//to swap the structure student arrays for sorting
void swap(struct student a,struct student b)
{
struct student t;
t=a;
a=b;
b=t;
}
void findweek(struct student ar[10],int l,int bd1,int bm1)
{
int count=0;
for(int i=0;i<l;i++)
{
int month_end=30;
int next_month=bm1+1;
//if(bd1>=23)
int end_date=bd1+7-month_end;
// else
int endofweek=bd1+7;
//l is length of ar , ar=copy of merged array, bd1&bm1 are date and month to search for birthday in that week
if((ar[i].m==bm1&&ar[i].bd>=bd1&&ar[i].bd<=endofweek)||ar[i].m==bm1+1&&ar[i].bd<=end_date)
{
if(month_end-bd1>7)
cout <<ar[i].name<<"\t"<<ar[i].prn<<"\t"<<ar[i].bd<<"|"<<ar[i].m<<endl;
else
{
if((ar[i].m==bm1&&ar[i].bd>=bd1)||(ar[i].m==next_month&&ar[i].bd<=end_date))
{
cout <<ar[i].name<<"\t"<<ar[i].prn<<"\t"<<ar[i].bd<<"|"<<ar[i].m<<endl;
}
}
count++;
if(count>7)
break;
}
}
}

It compiles even if you remove this line:
void swap(struct a,struct b);
Also, it compiles if you remove the whole swap function.
How is it?
Quite simple.
You are defining a function that takes two arguments: an incomplete type struct a and an incomplete type struct b.
That function is simply discarded from the overload set while searching the one to be used at function call.
Your main is not using your swap function. Instead, it's using the one from std:: namespace.
It is probably introduced by iostream or string, it's implementation defined.
Try changing the name of the function or putting a throw in your implementation of swap. In the second case, your runtime won't be affected.
Minimal, (not-)working example to reproduce the issue:
void f(struct s);
struct S {};
int main() { f(S{}); }
void f(S) {}
As you can see, the error is that you are referring to an incomplete type struct s.
swap is kinda of a somehow misleading example that compiles for the reasons above.
Reproducing an issue with a minimal example is often helpful.

Related

Compiler is throwing error in main that this is not declare before

#include<iostream>
#include<string>
using namespace std;
class customerNode{
public:
int c_id;
int quantity;
string c_name;
string type;
customerNode* next_node;
};
class Queue{
public:
customerNode* front=NULL;
customerNode* rear=NULL;
int getc_id();
string getc_name();
int getquantity();
int setc_id(int c_id);
string setc_name(string c_name);
int setquantity(int quantity);
void display();
void enqueue(int c_id,int quantity,string c_name);
void dequeue();
int nor_queue,exp_queue;
};
int Queue::getc_id(){
int c_id;
cout<<"enter customer id:"<<endl;
cin>>c_id;
return c_id;
}
int Queue::getquantity(){
int quantity;
cout<<"enter quantity customer purchased:"<<endl;
cin>>quantity;
return quantity;
}
string Queue::getc_name(){
string c_name;
cout<<"enter customer name:"<<endl;
cin>>c_name;
return c_name;
}
int Queue::setc_id(int c_id){
return c_id;
}
int Queue::setquantity(int quantity){
return quantity;
}
string Queue::setc_name(string c_name){
return c_name;
}
void Queue:: enqueue(int c_id,int quantity,string c_name){
int exp_queue,nor_queue;
cout<<"enter customer information"<<endl;
customerNode* new_node=new customerNode;
new_node->c_id=c_id;
new_node->c_name=c_name;
new_node->quantity=quantity;
new_node->next_node=NULL;
if(front==NULL){
rear=front;
rear=new_node;
rear->next_node=NULL;
}
else{
while(rear->next_node!=NULL)
rear=rear->next_node;}
rear->next_node=new_node;
rear=new_node;
if(new_node->quantity<=5)
{
new_node->type="express";
exp_queue++;
cout<<"customer entered in express queue"<<endl;
cout<<"total customer in express queue="<<exp_queue<<endl;
}
else{
new_node->type="normal";
nor_queue++;
cout<<"customer entered in normal queue"<<endl;
cout<<"total customer in normal queue="<<nor_queue<<endl;
}
}
void Queue::display(){
customerNode* ptr=front;
cout<<"normal queue customer information"<<endl;
while(ptr!=NULL)
{
if(ptr->type=="normal"){
cout<<"custumer name:"<<setc_name(ptr->c_name)<<endl;
cout<<"custumer id:"<<setc_id(ptr->c_id)<<endl;
cout<<"item puchased by custumer :"<<setquantity(ptr->quantity)<<endl;
nor_queue--;
cout<<"total customer in normal queue:"<<nor_queue<<endl;
}
ptr=ptr->next_node;
}
cout<<"express queue customer information"<<endl;
while(ptr!=NULL)
{
if(ptr->type=="normal"){
cout<<"custumer name:"<<setc_name(ptr->c_name)<<endl;
cout<<"custumer id:"<<setc_id(ptr->c_id)<<endl;
cout<<"item puchased by custumer :"<<setquantity(ptr->quantity)<<endl;
nor_queue--;
cout<<"total customer in normal queue:"<<exp_queue<<endl;
}
}
}
main(){
Queue q;
char i;
do{
q.enqueue(c_id,quantity,c_name );
cout<<"do you want to enter another customer?input y or Y for yes and n or N for no:";
cin>>i;
}
while(i=='y'||i=='Y');
q.display();
return(0);
};`
in mian fuction i m getting error c_id,quantity,c_name is not declare before,when i use int c_id,int quantity,string c_name than it shows expected primary expression befor int and strinng..i dont know which expression is missing or how to resolve the error,
please help me to solve this i hve to submit assing as soon as possible.
A much simpler example with similar error is:
#include <iostream>
struct foo {
int x = 0;
int y = 0;
void assign(int a, int b){
x = a;
y = b;
}
};
int main()
{
foo f;
f.assign(x,y);
}
The error is:
<source>: In function 'int main()':
<source>:14:14: error: 'x' was not declared in this scope
14 | f.assign(x,y);
| ^
<source>:14:16: error: 'y' was not declared in this scope
14 | f.assign(x,y);
| ^
x and y are declared in the scope of the class. Instances of foo have members of that name. To access those members you would write f.x or f.y.
c_id,quantity, and c_name are not declared in your main. I am not eniterly sure what you want to do and it is too much code to adress all its issues. Though, if you want to declare variables of that name in main then you need to do that:
int main(){ // main must return int
Queue q;
char i;
int c_id = 42;
int quantity = 0;
string c_name{"some fancy name"};
q.enqueue(c_id,quantity,c_name );
// ...
}
It is a little surprising that you write code with advanced stuff like pointers, classes and what not, but don't know about scope. Try to search for "scope" and read about it.
There are more issues in your code. For example int Queue::setquantity(int quantity){ return quantity;} does not set anything. Though, as I wrote before, this is just way too much code to adress all of them. I can only advise you to start with less code and only write more when you know the code you have already does compile and passes your tests. And thats not just an advise for a beginner, but anybody is making mistakes and you rather want to fix one problem then many at the same time.

How to print students name in ascending according to marks

I had sort the mark for all tests, quizzes, assignments and final exam in ASCENDING order. But I don't know how to display all student's name in ascending order based on their mark for each tests, quizzes, assignments and final exam.
Below are my code to sort each mark for tests, quizzes, assignments and final exam in ascending order. How to change the code so that it will display the students name, not the marks for each tests, quizzes, assignments and final exam?
Please, help. Thank you in advance.
#include <iostream>
#include <string>
using namespace std;
//global constant
const int NUM_STUDENTS=5;//row
const int NUM_SCORES=4;//col
string name[5]={"Hani","Haziq","Aiman","Farah","Sabrina"};
string mark[4]={"test","quiz","assignment","final exam"};
//Function prototypes
void ascenDescen(double [ ][NUM_SCORES],int);
int main ( )
{
cout<<"This program will help you keep track of your academic record!"<<endl;
double scores[NUM_STUDENTS][NUM_SCORES]=
{{9.0,2.7,16.0,78.0},
{7.4,2.7,19.0,88.0},
{8.9,3.5,17.5,93.7},
{10.0,3.0,19.5,64.8},
{6.3,3.0,16.0,74.2}};
//function call
ascenDescen(scores,NUM_STUDENTS);
cout<<endl;
cout<<"THANK YOU."<<endl;
return 0;
}
void ascenDescen (double table[][NUM_SCORES],int rows)
{
//for ascending
cout<<"Press ENTER to sort the mark for all tests, quizzes, assignments and final exam in ASCENDING order : \n\n";
char ch;
ch=cin.get();
double ascen;
for(int col=0;col<NUM_SCORES;col++)
{
for(int row=0;row<NUM_STUDENTS;row++)
{
for(int j=row+1;j<NUM_STUDENTS;++j)
{
if(table[row][col]>table[j][col])
{
ascen=table[row][col];
table[row][col]=table[j][col];
table[j][col]=ascen;
}
}
}
cout<<mark[col]<<" mark in ASCENDING order : \n";
for(int row=0;row<NUM_STUDENTS;row++)
{
cout<<" ";
cout<<table[row][col];
cout<<endl;
}
}
cout<<"________________________"<<endl;
}
A rule of thumb: If you need parallel arrays, chances are you should have a vector of struct.
Let's try modeling the data using a Student structure:
struct Student
{
std::string name;
std::vector<int> marks;
};
Thus far, every Student has a name and has some marks. The has-a relationship indicates composition. The is-a relationship indicates inheritance.
Let's add a sort method for the marks. The students will be easier to order by marks, if the marks are sorted.
struct Student
{
//...
void sort_marks()
{
std::sort(marks.begin(), marks.end()); // Assume default of `std::less<int>`
}
};
To perform an ordering other than the default, we'll need to define a custom ordering function:
bool Order_By_Marks(const Student& a, const Student& b)
{
bool a_is_less_than_b = true;
unsigned int quantity_of_marks = a.marks.size();
if (b.marks.size() < quantity_of_marks)
{
quantity_of_marks = b.marks.size();
}
for (unsigned int i = 0; i < quantity_of_marks; ++i)
{
if (a.marks[i] > b.marks[i])
{
a_is_less_than_b = false;
break;
}
}
return a_is_less_than_b;
}
To sort a database of Student by marks:
std::vector<Student> database;
// ... input students ...
for (i = 0; i < database.size(); ++i)
{
database[i].sort_marks();
}
std::sort(database.begin(), database.end(), Order_By_Marks);
You'll need to walk through the code with a debugger to verify the ordering of the student marks and also the ordering of the students by mark.
#include <iostream>
#include <string>
using namespace std;
//global constant
const int NUM_STUDENTS=5;//row
const int NUM_SCORES=4;//col
string name[5]={"Hani","Haziq","Aiman","Farah","Sabrina"};
string mark[4]={"test","quiz","assignment","final exam"};
struct student {
};
//Function prototypes
void ascenDescen(double [ ][NUM_SCORES],int);
int main ( )
{
cout<<"This program will help you keep track of your academic record!"<<endl;
double scores[NUM_STUDENTS][NUM_SCORES]=
{{9.0,2.7,16.0,78.0},
{7.4,2.7,19.0,88.0},
{8.9,3.5,17.5,93.7},
{10.0,3.0,19.5,64.8},
{6.3,3.0,16.0,74.2}};
//function call
ascenDescen(scores,NUM_STUDENTS);
cout<<endl;
cout<<"THANK YOU."<<endl;
return 0;
}
void ascenDescen (double table[][NUM_SCORES],int rows)
{
//for ascending
cout<<"Press ENTER to sort the mark for all tests, quizzes, assignments and final exam in ASCENDING order : \n\n";
cin.get();
double ascen;
string temp1[5] = name;
string temp2;
for(int col=0;col<NUM_SCORES;col++)
{
for(int row=0;row<NUM_STUDENTS;row++)
{
for(int j=row+1;j<NUM_STUDENTS;++j)
{
if(table[row][col]>table[j][col])
{
ascen=table[row][col];
temp2 = temp1[row];
table[row][col]=table[j][col];
temp1[row] = temp1[j];
table[j][col]=ascen;
temp1[j] = temp2;
}
}
}
cout<<mark[col]<<" mark in ASCENDING order : \n";
for(int row=0;row<NUM_STUDENTS;row++)
{
cout<<" ";
cout << temp1[row] << " " <<table[row][col];
cout<<endl;
}
for(int i = 0; i < NUM_STUDENTS; i++)
{
temp1[i] = name[i];
}
}
cout<<"________________________"<<endl;
}

What can't I delete a value defined by the user from a vector?

I am trying to use the vector erase function to delete a string that is an element of a vector for a homework assignment. I have tried the line two ways:
vectnames.erase(vectnames[blowup]);
vectnames.erase(blowup);
Does anyone know why the erase function might not be working? As a bit of background, I have to allow the user to enter a planet name to a vector and also let them delete it by name. The example I found online used line #2, but it's not working...
Here is the rest of my code for reference.
#include <iostream>
#include <string>
#include <cmath>
#include <vector>
using namespace std;
class planet
{
private:
string n;
double d, m;
public:
void Density (double d, double m)
{
double Den = m/((4.0/3.0)*M_PI*pow((d/2.0), 3.0));
cout<<"Density: "<<Den<<endl;
}
void SurfaceArea(double d)
{
double S = 4.0*M_PI*pow((d/2.0), 2.0);
cout<<"Surface Area: "<<S<<endl;
}
void Name (string n)
{
string N = n;
cout<<"Name: "<<N<<endl;
}
void Gravity (double G, double m, double d)
{
double F = G*m/pow((d/2.0), 2.0);
cout<<"Force of gravity: "<<F<<endl;
}
};
int main()
{
const double G=6.67384e-11;
int c=0;
string n, N, blowup;
double d=0.0, m=0.0, Den=0.0, S=0.0, F=0.0;
vector<string> vectnames;
vector<double> vectdiam;
vector<double> vectmass;
do
{
cout<<"1. Add a planet\n";
cout<<"2. Delete planet\n";
cout<<"3. Find planet (by name)\n";
cout<<"4. List all planets\n";
cout<<"5. Sort (alphabetical order)\n";
cout<<"6. Quit\n";
cout<<endl;
cout<<"Please select an option from the menu above."<<endl;
cin>>c;
cout<<endl;
if(c==1)
{
planet red;
cout<<"Enter the planet's name: ";
cin>>n;
cout<<"Enter the planet's diameter: ";
cin>>d;
cout<<"Enter the planet's mass: ";
cin>>m;
cout<<endl;
vectnames.push_back(n);
vectdiam.push_back(d);
vectmass.push_back(m);
red.Name(n);
red.Density(d, m);
red.SurfaceArea(d/2.0);
red.Gravity(G, m, d);
cout<<endl;
}
else if (c==2)
{
cout<<"Fire the Death Star's superlaser at: "<<endl;
cin>>blowup;
vectnames.erase(vectnames[blowup]); //This is the part that I'm having trouble with
for (int i=0; i<vectnames.size(); i++)
{
cout<<vectnames[i]<<endl;
}
}
else if (c==4)
{
for (int i=0; i<vectnames.size(); i++)
{
planet red;
cout<<"Planet name: "<<vectnames[i]<<endl;
cout<<"Planet diameter: "<<vectdiam[i]<<endl;
cout<<"Planet mass: "<<vectmass[i]<<endl;
red.Density(vectdiam[i], vectmass[i]);
red.SurfaceArea(vectdiam[i]/2.0);
red.Gravity(G, vectmass[i], vectdiam[i]);
cout<<"************************"<<endl;
cout<<endl;
}
}
} while (c!=6);
system("pause");
return 0;
}
I'm going to work with vector<planet> planets; because it's got a nice ring to it and it's purpose is about as close to obvious as I can get without using an idiotically long name like VectorOfPlanets.
In order to erase an item from a vector you have to know where it is. There are a bunch of ways to do this from brute force searching the vector in a loop until you find the index of the item you want and then calling planets.erase(planets.begin + index);
I thought there was a overload of std::find you could pass a comparator function, but it looks like I'm on crack. Glad I didn't make an ass of myself by suggesting it. Wait... Am I writing out loud? Crap. Hate it when I do that.
Read up on how to create an operator= method in the planet class and you can use std::find. With it you can:
vector<planet> planets;
vector<planet>::iterator it;
it = std::find(planets.begin(), planets.end());
if (it != planets.end())
{
planets.erase(it);
}

how to use gets function in c++ code?

In the main function of this code in the case 2 of switch case after entering the string program terminates! What is the problem with the code?
/*this code is a implementation of bubble sort algorithm*/
#include <iostream>
#include<conio.h>
#include<stdio.h>
#include<string.h>
#include<dos.h>
using namespace std;
int counter;
template <class T>//template created
class program//class which holds all the sorting functions
{
public:
T *v,x;
int j,k,l,siz,flag;
time_t t1,t2;
char c;
public:
void sortlist()//fn to sort characters and numbers
{
cout<<endl<<"------->>INTERMEDIATE STEPS<<-------";
for(k=1;k<=siz-1;k++)//sorting using a bubble sort
{ flag=0;
cout<<endl<<"PASS : "<<k<<endl;
j=0;
while(j<=siz-1-k)
{
if(v[j]>v[j+1])//comparing two consecutive elements
{
x=v[j+1];
v[j+1]=v[j];
v[j]=x;
flag++;
}
for(l=0;l<siz;l++)
{
cout<<v[l]<<" ";
}
cout<<endl;
j++;
}
cout<<"COMPARISONS:"<<(siz-k)<<endl;
if(flag==0)
{
cout<<endl<<"----->NO need to carry out more passes"<<endl<<"List is already sorted"<<endl;
break;
}
}
}
void stringsort()//fn to sort the strings
{
T a[90][20],b[1][20];
cout<<"enter the size of list:";
cin>>siz;
cout<<"enter the list:";
cin.ignore();
for(j=0;j<siz;j++)
{
gets(a[j]);
}
cout<<endl<<"------->>INTERMEDIATE STEPS<<-------";
for(k=1;k<=siz-1;k++)//sorting using bubble sort
{
flag=0;
cout<<endl<<"PASS : "<<k<<endl;
j=0;
while(j<siz-k)
{
x=strcmp(a[j],a[j+1]);//comparing two consecutive string
if(x>0)
{
strcpy(b[1],a[j+1]);
strcpy(a[j+1],a[j]);
strcpy(a[j],b[1]);
flag++;
}
for(l=0;l<siz;l++)
{
cout<<a[l]<<" ";
}
cout<<endl;
j++;
}
cout<<endl<<"COMPARISON:"<<(siz-k)<<endl;
if(flag==0)
{
cout<<endl<<"No need to carry out more passes"<<endl<<"List is already Sorted"<<endl;
break;
}
}
cout<<"SORTED LIST:"<<endl;
for(j=0;j<siz;j++)
{
cout<<endl<<a[j]<<endl;
}
}
};
int main()//main fn
{
int x;
char c;
do
{
program <char> p1;
program <int> p2;
cout<<endl<<"To sort a list of NUMBERS enter -> 1"<<endl<<endl<<"To sort string of CHARACTERS enter -> 2"<<endl<<endl<<"To sort a list OF STRINGS and DOUBLE_STRINGS enter -> 3";
cout<<endl<<endl<<"Enter either 1 OR 2 OR 3:";
cin>>x;
switch(x)
{
case 1://to sort list of numbers
{
cout<<endl<<"enter the size of list: ";
cin>>p2.siz;
cout<<"enter the list: "<<endl;
p2.v=new int[p2.siz];
for(p2.l=0;p2.l<=p2.siz-1;p2.l++)
{
cin>>p2.v[p2.l];
}
p2.sortlist();//sort and search in numbers
cout<<endl<<"SORTED LIST:"<<endl;//sorted list after the bubble sort
for(x=0;x<=(p2.siz)-1;x++)
{
cout<<p2.v[x]<<endl;
}
}
break;
case 2://to sort string of character
{
cout<<"enter the string of characters:";
cin.ignore()
gets(p1.v);
p1.siz=strlen(p1.v);
p1.sortlist();//sort in characters
cout<<endl<<"SORTED STRING:"<<p1.v;
}
break;
case 3://to sort list of strings
{
p1.stringsort();//sort list of string
}
break;
default:
cout<<"INVALID_CHOICE"<<endl<<endl;
}
cout<<endl<<"do u want to enter another list?y/n";
cin>>c;
}
while(c=='y');
return 0;
}
gets requires that you pass a pointer to enough storage space to hold the string that gets read. Your program passes an uninitialized pointer.
You're not really allowed to do anything with uninitialized values, so in theory your program can crash before it even enters the gets function.
Since the user can pass any amount of data to gets and your program would be responsible for storing it, the function is deprecated. It doesn't even exist any more in the C++ standard library as std::gets since 2011, although ::gets will probably always be available in POSIX. The short answer is, "don't."
You might consider std::string and std::getline instead.

Cannot create pointers of an abstract class in function main()

#include<iostream.h>
#include<conio.h>
#include<string.h>
class flight
{
private :
int flightno;
char source[30],destination[30];
protected :
double fare;
public :
flight()
{
flightno=0;
source[0]='\0';
destination[0]='\0';
fare=0.0 ;
}
flight(int f,char s[],char d[],double fr)
{
flightno=f;
strcpy(source,s);
strcpy(destination,d);
fare=fr;
}
flight(flight &f)
{
flightno=f.flightno;
strcpy(source,f.source);
strcpy(destination,f.destination);
fare=f.fare;
}
virtual void accept()
{
cout<<"\nEnter Fligt no :";
cin>>flightno;
cout<<"\nEnter source :";
cin.getline(source,30);
cout<<"\nEnter destination :";
cin.getline(destination,30);
cout<<"\nEnter fare :";
cin>>fare;
}
virtual void display()
{
cout<<"\nFlight number :"<<flightno;
cout<<"\nsource :"<<source;
cout<<"\nDestination :"<<destination;
cout<<"\nflight fare :"<<fare;
}
virtual double computefare()=0;
};
class domestic : public flight
{
private :
int noc,noa;
double totalfare,discount;
public :
domestic()
{
noc=0;
noa=0;
totalfare=0.0;
discount=0.0;
}
domestic(int f,char s[],char d[],double fr,int nc,int na):flight(f,s,d,fr)
{
noc=nc;
noa=na;
totalfare=0.0;
discount=0.0;
}
domestic(domestic &d):flight(d)
{
noc=d.noc;
noa=d.noa;
totalfare=d.totalfare;
discount=d.discount;
}
void accept()
{
flight::accept();
cout<<"\nEnter no. of adults :";
cin>>noa;
cout<<"\nEnter no. of children :";
cin>>noc;
}
void display()
{
flight::display();
cout<<"\n no. of adults :"<<noa;
cout<<"\n no. of children :"<<noc;
cout<<"\n total fare :"<<totalfare;
cout<<"\n discount :"<<discount;
if(discount!=0)
cout<<"After disc: "<<(totalfare-discount);
}
double computefare()
{
totalfare=noc*flight::fare*0.5+noa*flight::fare;
if(totalfare>40000)
discount=0.02*totalfare;
return totalfare-discount;
}
};
class internatinal : public flight
{
private :
int nop;
double totalfare,tax;
public :
internatinal()
{
nop=0;
totalfare=0.0;
tax=0.0;
}
internatinal(int f,char s[],char d[],double fr,int np):flight(f,s,d,fr)
{
nop=np;
totalfare=0.0;
tax=0.0;
}
internatinal(internatinal &i):flight(i)
{
nop=i.nop;
totalfare=i.totalfare;
tax=i.tax;
}
void accept()
{
flight::accept();
cout<<"\nEnter no. of passenger :";
cin>>nop;
}
void display()
{
flight::display();
cout<<"\n no. of passenger :"<<nop;
cout<<"\n total fare :"<<totalfare;
cout<<"\n tax :"<<tax;
cout<<"After tax: "<<(totalfare+tax);
}
double computefare()
{
totalfare=nop*flight::fare;
tax=0.30*totalfare;
return totalfare+tax;
}
};
int main()
{
int i,n,ch;
double total=0;
cout<<"\n Enter no of transaction :" ;
cin>>n;
flight *f=new flight[n];
for(i=0;i<n;i++)
{
cout<<"\n Enter 1 : domestic \n 2. internatinal :";
cin>>ch;
f[i]=ch==1?new domestic():new internatinal();
f[i]->accept();
total+=f[i]->computefare();
}
cout<<"\n totaL fare :"<<total;
getch();
return 0;
}
I am using turdo C++ complier . My code is not able to compile the error lies in the main() in "flight *f=new flight[n];" line (error is :1.)Cannot create instance of abstract
class 'flight' in function main()
2.) Class 'flight' is abstract because of 'flight::computefare() = 0' in function main() ).
As far as i can remember we cannot create objects of an abstract class but we can create pointers of it. And here i am creating pointers only but still m getting this error.
You're creating a pointer-to-flight, but you're also trying to create n flight objects: the array you're creating is an array-of-flight, not an array-of-pointer-to-flight.
So this cannot work.
You could use for instance a std::vector<flight*> (possibly using a smart pointer inside the container too). (Or an array of pointer-to-flight.)
For your assignment, don't try and scrunch it all up in a single line, it buys you nothing. Write it more clearly and it will work:
if (ch == 1)
f[i] = new domestic();
else
f[i] = new internatinal();
(The other option is to use a cast, but that will make that line even less readable.)