I wanted to declare a constructor but I face this error. As it's obvious , I wanted to create a program to show the polar form of a complex number. I know it's kind of ridiculous and it's easier to do this , with functions . BUT this is a project and it is mentioned not to change the body of main function.
How can this be fixed?
#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std;
class Complex
{
public:
double real , img;
Complex()
{
real = 0;
img = 0;
}
};
class constructComplex : public Complex
{
public:
constructComplex(double a , double b)
{
real = a;
img = b;
}
};
class printPolarForm : public Complex
{
public:
printPolarForm(Complex z)
{
cout << fixed << setprecision(2);
double r = sqrt( z.real * z.real + z.img * z.img );
double argument = atan2(z.img , z.real)*180/3.14;
cout << r << "e^(i" << argument << ')';
}
};
int main()
{
cout << fixed << setprecision(2);
double x1, y1;
cin >> x1 >> y1;
Complex c = constructComplex(x1, y1);
printPolarForm(c);
return 0;
}
You have a serious misunderstanding of what classes are for. Generally speaking classes encapsulate some state, i.e. member variables, and some operations on that state. None of your last two classes above have any state beyond the Complex class that they inherit from, so they should not exist as classes.
Let's see how this code should be written
constructComplex is an attempt to construct a complex number from parameters, so it should be an alternate constructor within the Complex class. i.e.
class Complex
{
public:
double real , img;
Complex()
{
real = 0;
img = 0;
}
Complex(double a, double b)
{
real = a;
img = b;
}
};
With this new constructor your main code changes from
Complex c = constructComplex(x1, y1);
to
Complex c(x1, y1);
printPolarForm is an operation on an existing complex number. It could be defined as a member function or a free function. I'll show that as a free function first
void printPolarForm(Complex z)
{
cout << fixed << setprecision(2);
double r = sqrt( z.real * z.real + z.img * z.img );
double argument = atan2(z.img , z.real)*180/3.14;
cout << r << "e^(i" << argument << ')';
}
the alternative is to make is a member function of the Complex class
class Complex
{
...
void printPolarForm() const
{
cout << fixed << setprecision(2);
double r = sqrt( real * real + img * img );
double argument = atan2(img , real)*180/3.14;
cout << r << "e^(i" << argument << ')';
}
};
The rest of the Complex class is as before. With the member function method you have to change how the function is called in main. Instead of
printPolarForm(c);
you would write
c.printPolarForm();
Either of these two options (free function or member function) are perfectly acceptable in this case. In both cases the class printPolarForm has been removed.
As I understand it(Jtime time1 = Jtime(1,2,4);), shouldn't the left and right sides of this statement call the constructor once
class Jtime
{
public:
Jtime(){ std::cout << "No argument constructor"; }
Jtime(double h, double M, double S)
{
std::cout << "There is a parameter constructor H M S";
Hours_ = h; Minte_ = M; Sencon_ = S;
}
~Jtime() = default;
private:
double Hours_;
double Minte_;
double Sencon_;
};
int main()
{
Jtime time1 = Jtime(1,2,4);
}
I am trying to learn how to use c++11 user defined literals for units of physical properties. The question is, how do I avoid a mixing of these units. So that (8.0_kg + 8.0_km)--> gives error. any ideas guys? i am new to c++, be kind.
class Mass{
public:
//Mass(){
// cout << "only Mass units allowed in here" << endl;
//}
//~Mass();
long double getWeight(long double a);
double car, house, cat;
private:
long double a;
};
long double Mass::getWeight(long double w) {
cout << "returning argument: " << w << '\n'<< endl;
return 0;
}
long double operator"" _km(long double d) { return d * 1000.0; }
long double operator"" _m (long double d) {return d;}
long double operator"" _cm(long double d) { return d / 100.0; }
long double operator"" _tonne(long double m) { return m * 1000.0 ; }
long double operator"" _kg(long double m) { return m ; }
long double operator"" _lb(long double m) { return m * 0.453592; }
long double getDistance(long double d){
long double starting_d = 61.0_kg;
long double total_d = d + starting_d;
cout << "the distance I have run is: " << total_d << endl;
return 0;
}
int main() {
cout << 6.0_km << endl;
cout << 6.0_km + 3.0_m << endl;
cout << 6.0_km + 3.0_m + 15.0_cm << '\n' << endl;
cout << 8.0_tonne << endl;
cout << 8.0_km + 4.0_kg << endl;
cout << 8.0_km + 4.0_kg + 21.0_lb << '\n' << endl;
long double distance = 5.45_km;
getDistance(distance);
Mass obj1;
obj1.getWeight(13.96_lb);
cout << "This is clearly wrong: "<< 8.0_km + 4.0_kg << endl;
obj1.getWeight(10.96_km); // so is this
}
You need to define your own types, since you can't restrict what a primitive represents.
You can use a "tagged template"1 to avoid repetition of operators and such and keep it type safe.
This can be extended so you get for instance distance * distance = area or speed * time = distance checked by the compiler.
Here's a short example:
template<typename Kind>
struct Value
{
long double value;
Value& operator+= (Value v) { value += v.value; return *this; }
};
template <typename Kind>
Value<Kind> operator+ (Value<Kind> lhs, Value<Kind> rhs) { return lhs += rhs; }
// These types don't need definitions; we only need some unique type names.
struct M;
struct D;
using Mass = Value<M>;
using Distance = Value<D>;
Mass operator"" _kg(long double d) { return { d };}
Mass operator"" _lb(long double d) { return { d * 0.453592 };}
Distance operator"" _km(long double d) { return { d * 1000 };}
Distance operator"" _mile(long double d) { return { d * 1609 };}
int main()
{
// OK
Distance d = 1.2_km + 0.2_mile;
// OK
Mass m = 2.3_kg + 1.4_lb;
// invalid operands to binary expression ('Distance' (aka 'Value<D>')
// and 'Mass' (aka 'Value<M>'))
Distance d2 = 2.4_km + 1.2_kg; // Nope
}
1) I don't think there's an established term in C++, but it's very similar to what Haskell refers to as phantom types.
Create classes representing numeric values of the different units. That's how it's been done since long before C++ 11.
Custom literals can make instantiation more readable, though, because it helps preserve the usual order of number and unit :)
See http://en.cppreference.com/w/cpp/language/user_literal
class MassKg
{
double value;
// public c'tor, numeric operators, &c.
};
// ...
MassKg mass(5.0);
DistanceM distance(3.0);
auto c = mass * distance; // may yield an instance of TorqueKgM, or MomentumKgM, therefore
// explicit functions / methods are preferrable for mixed
// multiplication or division
auto mass2 = mass + MassKg(2.0); // yiels an instance of MassKg
auto invalid = mass + distance; // compile time error
I have modified both the user defined classes to have constructors that accepts an object of the other class as it's argument.
Does this cover all the bases or do I have to overload the assignment operator and the type-cast operator as well to handle all the implicit and explicit type casting cases?
Eg:
#include <iostream>
using namespace std;
class Celsius; // Forward Declaration
class Fahrenheit {
double temp;
public:
Fahrenheit(double d = 0.0) : temp(d) {}
Fahrenheit(Celsius);
void setTemp(double d) { temp = d; }
double getTemp() { return temp; }
void print() { cout << "\nThe temperature value in Fahrenheit is " << temp << endl; }
};
class Celsius {
double temp;
public:
Celsius(double d = 0.0) : temp(d) {}
Celsius(Fahrenheit f) { temp = ((f.getTemp()-32) * 5) / 9; }
void setTemp(double d) { temp = d; }
double getTemp() { return temp; }
void print() { cout << "\nThe temperature value in Celsius is " << temp << endl; }
};
Fahrenheit::Fahrenheit(Celsius c) { temp = ((c.getTemp() * 9) / 5) + 32; }
int main() {
Fahrenheit t1(20);
Celsius t2(t1);
Fahrenheit t3(50);
t2.print();
t2 = (Celsius) t3;
t2.print();
cin.get();
return 0;
}
I have an array of objects which all derive from the class BaseStudent.
BaseStudent**studentlist = new BaseStudent*[atoi(listSize.c_str())];
That array is populated with either derived Math, English or History objects. I'm now trying to print out specific data from each object in the array and output it to a file.
for (int j=0; j<atoi(listSize.c_str()); j++){
if(studentlist[j]->getMT() == ENGLISH){
output << studentlist[j]->GetFN()<<" "<<studentlist[j]->GetLN();
output << right << setw(42) << studentlist[j]->GetFinal(); // this is an English public function but I can't call this.
}
}
I need to be able to access the derived classes private member data from the array of objects.
Here's my header. As you can see I have a setter and getter for every protected member data.
#include <iostream>
#include <string>
using namespace std;
#ifndef BASESTUDENT_H
#define BASESTUDENT_H
enum MajorType {ENGLISH, HISTORY, MATH};
// *********************************************************************
// Base class. All other classes (Enlish, History, Math) inherit from
// this class.
// *********************************************************************
class BaseStudent
{
public:
BaseStudent();
BaseStudent(string fn, string ln, string m);
string GetFN(){return firstName;}
string GetLN(){return lastName;}
MajorType getMT(){return course;}
void SetFN(string fn){firstName = fn;}
void SetLN(string ln){lastName = ln;}
void SetMT(string m);
protected:
string firstName;
string lastName;
MajorType course;
}; // End Base class
// *********************************************************************
// Enlish class.
// *********************************************************************
class English: public BaseStudent
{
public:
English(string fn, string ln, string m, double a, double p, double mt, double f);
double FinalAverage();
double GetAttendance(){return attendance;}
double GetProject(){return project;}
double GetMidterm(){return midterm;}
double GetFinal(){return final;}
double GetFinalAverage(){return finalAverage;}
void SetAttendance(double a){attendance = a;}
void SetProject(double p){project = p;}
void SetMidterm(double m){midterm = m;}
void SetFinal(double f){final = f;}
void SetFinalAverage(double fa){finalAverage = fa;}
protected:
double attendance;
double project;
double midterm;
double final;
double finalAverage;
}; // End English class
// *********************************************************************
// History class.
// *********************************************************************
class History: public BaseStudent
{
public:
History(string fn, string ln, string m, double t, double mt, double f);
double FinalAverage();
double GetTermPaper(){return termPaper;}
double GetMidterm(){return midterm;}
double GetFinalExam(){return finalExam;}
double GetFinalAverage(){return finalAverage;}
double FinalExam(){return finalExam;}
void SetTermPaper(double t){termPaper = t;}
void SetMidterm(double m){midterm = m;}
void SetFinalExam(double f){finalExam = f;}
void SetFinalAverage(double fa){finalAverage = fa;}
protected:
double termPaper;
double midterm;
double finalExam;
double finalAverage;
}; // End History class.
// *********************************************************************
// Math class.
// *********************************************************************
class Math: public BaseStudent
{
public:
Math(string fn, string ln, string m, double q1, double q2, double q3,
double q4, double q, double t1, double t2, double f);
double FinalAverage();
double GetQuiz1(){return quiz1;}
double GetQuiz2(){return quiz2;}
double GetQuiz3(){return quiz3;}
double GetQuiz4(){return quiz4;}
double GetQuiz5(){return quiz5;}
double GetFinalExam(){return finalExam;}
double GetTest1(){return test1;}
double GetTest2(){return test2;}
double GetQuizAverage(){return quizAverage;}
double GetFinalAverage(){return finalAverage;}
void SetQuiz1(double q){quiz1 = q;}
void SetQuiz2(double q){quiz2 = q;}
void SetQuiz3(double q){quiz3 = q;}
void SetQuiz4(double q){quiz4 = q;}
void SetQuiz5(double q){quiz5 = q;}
void SetTest1(double q){test1 = q;}
void SetTest2(double q){test2 = q;}
void SetFinalExam(double q){finalExam = q;}
void SetQuizAverage();
void SetFinalAverage(double fa){finalAverage = fa;}
protected:
double quiz1;
double quiz2;
double quiz3;
double quiz4;
double quiz5;
double test1;
double test2;
double finalExam;
double quizAverage;
double finalAverage;
}; // End Math class.
#endif
Do I need some sort of implementation of virtual functions?
Here's my driver so far:
#include<iostream>
#include<fstream>
#include<string>
#include<iomanip>
#include"basestudent.h"
using namespace std;
int main(void)
{
string listSize;
string fileIn = "";
string fileOut = "";
string firstname ="";
string lastname ="";
string major = "";
string eolDummy;
int mQuiz1, mQuiz2, mQuiz3, mQuiz4, mQuiz5, mTest1, mTest2, mFinalExam;
int eAttendance, eProject, eMidterm, eFinalExam;
int hTermPaper, hMidterm, hFinalExam;
ifstream input;
ofstream output;
do{
input.clear();
cout << "Please enter the filename: ";
cin >> fileIn;
cout << "Please enter an output name: ";
cin >> fileOut;
input.open(fileIn);
if (!input)
cout << "Invalid file, please enter again." << endl;
} while(!input);
input >> listSize;
BaseStudent**studentlist = new BaseStudent*[atoi(listSize.c_str())];
int i = 0;
while (!input.eof())
{
getline(input, lastname, ',');
getline(input, firstname, '\n');
input >> major;
if (major == "Math") {
input >>mQuiz1>>mQuiz2>>mQuiz3>>mQuiz4>>mQuiz5>>mTest1>>mTest2
>>mFinalExam>>eolDummy;
// Math Constructor call
// Array += object
studentlist[i] = new Math(firstname,lastname,major,mQuiz1,mQuiz2,mQuiz3,mQuiz4,mQuiz5,
mTest1,mTest2,mFinalExam);
}
else if (major == "History"){
input >>hTermPaper>>hMidterm>>hFinalExam>>eolDummy;
// History Constructor call
// Array += object
studentlist[i] = new History(firstname,lastname,major,hTermPaper,hMidterm,hFinalExam);
}
else if(major == "English"){
input >>eAttendance>>eProject>>eMidterm>>eFinalExam>>eolDummy;
// English Constructor call
// Array += object
studentlist[i] = new English(firstname,lastname,major,eAttendance,eProject,eMidterm,eFinalExam);
}
i++;
}
output.open(fileOut);
output << "Student Grade Summary" << endl;
output << "---------------------" << endl << endl;
output << "ENGLISH CLASS "<<endl<<endl;
output << "Student Final Final Letter"<<endl;
output << "Name Exam Avg Grade"<<endl;
output << "----------------------------------------------------------------"<<endl;
for (int j=0; j<atoi(listSize.c_str()); j++){
if(studentlist[j]->getMT() == ENGLISH){
output << studentlist[j]->GetFN()<<" "<<studentlist[j]->GetLN();
output << right << setw(42) << studentlist[j]->
input.close();
output.close();
return 0;
}
When you take the pointer from your array, you need to cast it using dynamic_cast to the appropriate class
e.g.
BaseStudent *p = somearray[0];
if ( English* pEnglish = dynamic_cast<English*>(p) )
{
// call the methods
cout << p->FinalAverage();
...
}
else if ( History* pHistory = dynamic_cast<History*>(p) )
{
// call the methods
}
else if ( Math* pMath = dynamic_cast<Math*>(p) )
{
// call the methods
}
btw use a vector instead of a raw array, it is more convenient and safer.
std::vector<BaseStudent*> yourvector;