C++ Nonstatic member referencing must be relative to specific object - c++

This Complex Number program is supposed to take three arguments from a txt document, the first to indicate whether the subsequent two are numbers in polar or rectangular form, and output every complex number given in both rectangular and polar form. Both the header file and source code are shown here. The txt document is in the following format:
p 50 1.2
r 4 0.8
r 2 3.1
p 46 2.9
p 3 5.6
Without declaring the int inputfile() function as static within the class declarations, the build gives an error 'illegal call of non-static member function'.
With the static declaration of the function (shown below), the build gives errors referring to the class members Pfirst, Psecond, Rfirst and Rsecond inside function definition inputfile(), being 'illegal references to non-static members'.
The member declarations cannot then be made static as well because the class would not be able to initialise the parameters within the constructor.
How can I bypass this 'static' problem?
#define Complex_h
class Complex
{
char indicator;
const double pi;
public:
double Pfirst, Psecond, Rfirst, Rsecond;
Complex(char i = 0, double Pf = 0, double Ps = 0, double Rf = 0, double Rs = 0, const double pi = 3.14159265) // with default arguments (= 0)
: indicator(i), Pfirst(Pf), Psecond(Ps), Rfirst(Rf), Rsecond(Rs), pi(pi) {}
~Complex();
void poltorect();
void recttopol();
static int inputfile();
};
#include <iostream>
#include <iomanip>
#include <fstream>
#include <sstream>
#include <string>
#include "Complex.h"
using namespace std;
int Complex::inputfile()
{
ifstream ComplexFile;
ComplexFile.open("PolarAndRectangular.txt");
string TextArray[3];
string TextLine;
stringstream streamline, streamfirst, streamsecond;
while (getline(ComplexFile,TextLine))
{
streamline << TextLine;
for (int j=0; j<3; j++)
{streamline >> TextArray[j];}
streamline.str("");
streamline.clear();
if (TextArray[0] == "r")
{
streamfirst << TextArray[1];
streamfirst >> Rfirst;
streamsecond << TextArray[2];
streamsecond >> Rsecond;
cout << "Complex number in rectangular form is " << Rfirst << "," << Rsecond << endl;
void recttopol();
cout << "Complex number in polar form is " << Pfirst << "," << Psecond << endl;
}
else
{
streamfirst << TextArray[1];
streamfirst >> Pfirst;
streamsecond << TextArray[2];
streamsecond >> Psecond;
cout << "Complex number in polar form is " << Pfirst << "," << Psecond << endl;
void poltorect();
cout << "Complex number in rectangular form is" << Rfirst << "," << Rsecond << endl;
}
streamfirst.str("");
streamfirst.clear();
streamsecond.str("");
streamsecond.clear();
}
ComplexFile.close();
system("pause");
return 0;
}
void Complex::recttopol()
{
Pfirst = sqrt((Rfirst*Rfirst)+(Rsecond*Rsecond));
Psecond = (atan(Rsecond/Rfirst))*(pi/180);
}
void Complex::poltorect()
{
Rfirst = Pfirst*(cos(Psecond));
Rsecond = Pfirst*(sin(Psecond));
}
int main()
{
Complex::inputfile();
system("pause");
return 0;
}

You forgot to create an object of type Complex.
Make your inputfile() method nonstatic and do:
int main()
{
Complex complex; // Object construction.
complex.inputfile();
system("pause");
return 0;
}

Related

Is there a way to use google test on OOP program?

I'm new to google test and currently I'm writing a test for my OOP program, my OOP program is like this:
#include <iostream>
#include <gtest/gtest.h>
using namespace std;
typedef unsigned int NUM;
class Employee
{
protected:
NUM MaSoThue;
private:
NUM Luong;
NUM CMND;
NUM a;
NUM b;
public:
Employee()
{
MaSoThue = 0;
Luong = 0;
CMND = 0;
}
Employee(NUM mst, NUM luong, NUM cmnd)
{
MaSoThue = mst;
Luong = luong;
CMND = cmnd;
}
//get
int getMaSoThue() const { return MaSoThue; }
int getLuong() const { return Luong; }
int getCMND() const {return CMND;}
//set
void setMaSoThue(NUM mst) {if (MaSoThue==0) MaSoThue = mst;}
void setLuong(NUM luong) {Luong = luong;}
void setCMND(NUM cmnd) {if (CMND==0) CMND = cmnd;}
};
int main()
{
// Objects
Employee PhucTri(111,222,333);
Employee MinhDang;
MinhDang.setMaSoThue(1234);
MinhDang.setLuong(2);
MinhDang.setCMND(8888);
//PhucTri
cout <<"MST cua Phuc Tri: "<< PhucTri.getMaSoThue()<<"\n";
cout << "Luong cua Phuc Tri: " << PhucTri.getLuong() << "\n";
cout << "CMND cua Phuc Tri: " << PhucTri.getCMND() << "\n\n";
//MinhDang
cout << "MST cua Minh Dang: " << MinhDang.getMaSoThue() << "\n";
cout << "Luong cua Minh Dang: " << MinhDang.getLuong() << "\n";
cout << "CMND cua Minh Dang: " << MinhDang.getCMND() << "\n";
}
I created a new file, which is below:
#include <gtest/gtest.h>
#include "FileCode.cc"
int main(){}
TEST(No1, PhucTri){
EXPECT_EQ(PhucTri.getMaSoThue(),111);
}
The compiler says that the object "PhucTri" isn't declared in this scope, but I did create it in my first file, is there any way I can get it right on the object ?
In general, Try to not include .cpp files, declare your class and its methods inside a .h file, define methods in .cpp and then create a test file that includes your header.
You have two options here, either define a test class that has an instance of your class follows instructions here.
Or do something like this :
#include <gtest/gtest.h>
#include "FileCode.h"
TEST(No1, PhucTri)
{
Employee PhucTri(111,222,333);
// initialize your data
// ......
EXPECT_EQ(PhucTri.getMaSoThue(),111);
}

Why are my member functions/class variables outputting the wrong numbers?

I am learning how to use classes in c++. Right now I'm working on a small program which should display the miles per gallon of a vehicle based on the given number of miles and gallons. The assignment says to call member functions within the main function in order to set the member variables within the Auto class. Here is my code:
#include <iostream>
using namespace std;
class Auto {
public:
string model;
int milesDriven;
double gallonsOfGas;
double calculateMilesPerGallon(int milesDriven, double gallonsOfGas) {
return milesDriven / gallonsOfGas;
}
void setModel(string newModel){
model = newModel;
}
void setMilesDriven(int newMiles){
milesDriven = newMiles;
}
void setGallonsOfGas(double newGallons){
gallonsOfGas = newGallons;
}
void output(){
cout << "A " << model << " was driven " << milesDriven << " miles, and used " << gallonsOfGas << endl;
cout << "This car gets " << calculateMilesPerGallon(milesDriven, gallonsOfGas) << "mpg.";
}
};
int main()
{
Auto modelFunction;
Auto milesFunction;
Auto gasFunction;
Auto outputFunction;
string carModel = "Toyota Camry";
int carMiles = 100;
double carGallons = 10;
modelFunction.setModel(carModel);
milesFunction.setMilesDriven(carMiles);
gasFunction.setGallonsOfGas(carGallons);
outputFunction.output();
return 0;
}
It's supposed to display something like "A Toyota Camry was driven 100, and used 10 gallons of gas, and gets 10 mpg." Instead, my output shows "A was driven -1538932792 miles, and used 4.66265e-310
This car gets -infmpg." What am I doing that is causing the output to be like this? I just started using classes so I don't have much experience with them. Thanks for the advice.
The error you're encountering is because you're creating four different Auto objects, each of which will have their own member variables. If you change your main function to the following, it will work:
int main()
{
Auto car;
string carModel = "Toyota Camry";
int carMiles = 100;
double carGallons = 10;
car.setModel(carModel);
car.setMilesDriven(carMiles);
car.setGallonsOfGas(carGallons);
car.output();
return 0;
}
Note that there is now only one 'Auto' object entitled 'car'.
You have to create only one instance of class Auto cause you only want to show the info for one car (with the name "Toyota Camry").
#include <iostream>
using namespace std; // strongly encouraging you to avoid using this
// in file scope
class Auto {
public:
string model;
int milesDriven;
double gallonsOfGas;
double calculateMilesPerGallon(/*no params required*/) {
return milesDriven / gallonsOfGas;
}
void setModel(string newModel){
model = newModel;
}
void setMilesDriven(int newMiles){
milesDriven = newMiles;
}
void setGallonsOfGas(double newGallons){
gallonsOfGas = newGallons;
}
void output(){
cout << "A " << model << " was driven " << milesDriven << " miles, and used " << gallonsOfGas << endl;
cout << "This car gets " << calculateMilesPerGallon() << "mpg.";
}
};
int main()
{
string carModel = "Toyota Camry";
int carMiles = 100;
double carGallons = 10;
Auto car;
car.setModel(carModel);
car.setMilesDriven(carMiles);
car.setGallonsOfGas(carGallons);
car.output();
return 0;
}

Access to the struct elements. Is it possible to access like a vector?

I have the following example (simplified) using a struct:
#include <iostream>
#include <algorithm>
#include <time.h>
using namespace std;
struct s_str
{
int a=1,b=2,c=3;
};
int main(void)
{
s_str str;
int sel;
srand(time(NULL)); //initialize random seed
sel = rand() % (3); //generate a random number between 0 and 2
cout << "sel: " << sel << endl;
cout << "str: " << str.??? << endl;//I was wondering to output a, b or c
return 0; //depending whether sel=0,1,2respectively.
}
When the struct "str" is defined, we can access to each element by using the opertor "." followed by the name of the element. For instance "str.c" will give us the number 3.
However in this example we don't know the element of "str" to output when programing because it's randomly selected by sel.
I don't know how to output "str.???" from sel number, that is, str.a if sel=0, str.b if sel=1, and str.c if sel=3.
I tried something like "str.[sel]", but it didn't work. Can you help me?
PD: I don't want to bother too much, but how to solve the same problem but now supposing that a,b and c have different variable type. For example:
int a=1,b=2;
string c="hola";
I tried to do it with two operators, but it didn't compile because they were overloaded.
As mentioned you can't do this without providing a certain mapping and indexing operator. The following should work well:
struct s_str
{
int a=1,b=2,c=3;
int& operator[](int index) {
switch(index) {
case 0:
return a;
case 1:
return b;
case 2:
return c;
default:
throw std::out_of_range("s_str: Index out of range.");
break;
}
}
};
int main() {
s_str s;
cout << s[0] << ", " << s[1] << ", " << s[2] << endl;
// cout << s[42] << endl; // Uncomment to see it fail.
return 0;
}
In general, no.
If the only distinguishing feature of the elements of the struct is their index, define a vector or array in the struct.
If you sometimes want to refer to the elements by name and sometimes by position, define an operator []( int ) for the struct.
Te easiest way, if you have only a couple of ints in your structure is:
struct s_str
{
int a = 1, b = 2, c = 3;
int& operator[] (size_t t) {
assert(t<3); // assumption for the following to return a meaningful value
return (t == 0 ? a : (t == 1 ? b : c));
}
};
You'd access with
cout << "str: " << str[sel] << endl;
and you could even use int to assign, because it's by reference:
str[sel] = 9;
cout << "a,b,c=" << str.a << "," << str.b << "," << str.c << endl;

c++ Passing a value the wrong way?

When i am passing an object to a function, I am getting undesired results. It seems to happen when I pass a Character through a Mage's action() function.
Here are some snippits of my code:
character.h
class Character {
public:
Character();
int getMaxLives() const;
int getMaxCraft() const;
protected:
maxLives;
maxCraft;
};
character.cpp
#include "character.h"
Character::Character () {
maxLives = 5;
MaxCraft = 10;
}
int Character::getMaxLives() const {
return maxLives;
}
int Character::getMaxCraft() const {
return maxCraft;
}
mage.h
#include "character.h"
class Mage {
public:
Mage();
void action(Character c1);
};
mage.cpp
#include "mage.h"
Mage::Mage () { ... }
void Mage::action(Character c1) {
cout << "Max Craft: " << c1.getMaxCraft() << endl;
cout << "Max Lives: " << c1.getMaxLives() << endl;
}
driver.cpp
int main () {
Character c1;
Mage m1;
m1.action(c1);
My ouput gives me the following:
Max Craft: 728798402 (The number varies)
Max Lives: 5
However, if in my diver, i do:
cout << "Max Craft: " << c1.getMaxCraft() << endl;
cout << "Max Lives: " << c1.getMaxLives() << endl;
I get:
Max Craft: 10
Max Lives: 5
Any ideas?
Looks like you meant for MaxCraft = 10; (in your default constructor) to actually be maxCraft = 10;. As #chris says in the comments, it appears that you're using some (evil, evil) C++ extension that allows implicitly-typed variables, so the MaxCraft = 10; line is simply defining a new variable named MaxCraft.

C++ simple class declaration program

I got a program to create in C++ in our introduction to C++ class in school. I am doing everything as I got in examples, but still getting errors.
w4x.cpp was given and I have to create Molecule.h and Molecule.cpp. I did that, but I am getting errors because my variables were not declared in scope, but I can't understand why.
// w4x.cpp
#include <iostream>
using namespace std;
#include "w4x.h"
#include "Molecule.h"
int main() {
int n = MAX_MOLECULES;
Molecule molecule[MAX_MOLECULES];
cout << "Molecular Information\n";
cout << "=====================" << endl;
for (int i = 0; i < MAX_MOLECULES; i++) {
if (!molecule[i].read()) {
n = i;
i = MAX_MOLECULES;
}
cout << endl;
}
cout << "Structure Name Mass\n";
cout << "==================================================" << endl;
for (int i = 0; i < n; i++)
molecule[i].display();
}
//Molecule.h
const int MAX_STRUCT = 10;
const int MAX_NAME = 20;
class Molecule {
char name[MAX_STRUCT];
char rate[MAX_NAME];
double weight;
public:
Molecule();
void read(const char*, const char*, double);
void display() const;
~Molecule();
};
//Molecule.cpp
#include <iostream>
#include <cstring>
using namespace std;
#include "Molecule.h"
Molecule::Molecule(){
name[0]= '\0';
rate[0]= '\0';
weight = 0;
}
void::read(const char* n, const char* r, double w) {
weight = w;
strncpy (name, n, MAX_STRUCT);
name[MAX_STRUCT]='\0';
strncpy (rate, r, MAX_NAME);
rate[MAX_NAME]='\0';
cout << "Enter structure : ";
cin.getline (n, MAX_CHARS);
cout << "Enter full name : ";
cin.getline (r, MAX_NAME);
cout << "Enter weight : ";
cin >> w;
}
void::display() const
{
int x;
for ( x=0; x<i; x++)
cout << n << " " << r << " " << w << endl;
}
My first question is, how can I pass char name[MAX_STRUCT]; char rate[MAX_NAME]; double weight; from Molecule.h to Molecule.cpp
The problem with your definitions is here:
void::read(const char* n, const char* r, double w)
and here
void::display() const
What :: says here, is that you are implementing a function within a class. So you need to specify which class and which function! What you are telling it now, is that you are implementing a function inside class void, which is nonexistent.
You should convert them to:
void Molecule::read(const char* n, const char* r, double w)
void Molecule::display() const
Your other question regarding passing class members:
The functions of a class have access to its variables, therefore, you don't need to concern yourself with that. Just use the variables.
Also, if you notice in your w4x.cpp, the function Molecule::read() is called without parameters, so your TAs ask you to implement it without parameters. Indeed, since you have access to Molecule::name, Molecule::rate and Molecule::weight directly, you should read data and write to those variables instead of asking for parameters. Therefore, your read function would look like this:
void Molecule::read()
{
// read into name, rate and weight
}
Furthermore, w4x.cpp expects read to report whether it has been successful or not. This means that you should do error checking in Molecule::read and return 0 if no errors or -1 (for example) in case of errors.