Error while adding Complex numbers - c++

In below program I am getting 2 errors at below lines.
r = sum(p,q); //Function sum should have a prototype.
r = sum(p,q); //Cannot convert int to complex
Kindly advise the changes in the code.
Note: I have to do the code by passing objects of complex class to add and also the addition should return a complex number.
#include<iostream.h>
#include<conio.h>
class Complex
{
private:
int real;
int imag;
public:
void getNo()
{
cout<<"Enter real part : "<<endl;
cin>>real;
cout<<"Enter imaginary part : "<<endl;
cin>>imag;
}
void showNo()
{
cout<<real<<"+"<<imag<<"i";
}
Complex sum(Complex, Complex);
};
Complex Complex :: sum(Complex c1, Complex c2)
{
Complex a;
a.real = c1.real + c2.real;
a.imag = c1.imag + c2.imag;
return a;
}
void main()
{
clrscr();
Complex p,q,r,s;
p.getNo();
q.getNo();
cout<<endl<<"First complex number is : ";
p.showNo();
cout<<endl<<"Second complex number is : ";
q.showNo();
r = sum(p,q);
cout<<"Addtion of the complex no is : ";
r.showNo();
getch();
}

For your purpose the "sum" function should not be in the "Complex" class. Here a bit changed code:
#include <iostream>
#include <conio.h>
using namespace std;
class Complex
{
public:
int real;
int imag;
void getNo ()
{
cout << "Enter real part : " << endl;
cin >> real;
cout << "Enter imaginary part : " << endl;
cin >> imag;
}
void showNo ()
{
cout << real << "+" << imag << "i";
}
};
Complex sum (Complex c1, Complex c2);
int main ()
{
//clrscr ();
Complex p, q, r, s;
p.getNo ();
q.getNo ();
cout << endl << "First complex number is : ";
p.showNo ();
cout << endl << "Second complex number is : ";
q.showNo ();
r = sum (p, q);
cout << endl << "Addtion of the complex no is : ";
r.showNo ();
getch ();
}
Complex sum (Complex c1, Complex c2)
{
Complex
a;
a.real = c1.real + c2.real;
a.imag = c1.imag + c2.imag;
return a;
}
Edit
Functions in class require an instance (object) of class.
Simply you CAN do this:
p.getNo();
t.sum();
myComplexNum.getReal();
But in your code you are trying to do this which you CAN NOT:
a = getNo();
b = sum();
getReal();
Additionally you CAN make the function static like other answer.
static functions and variables does not require an instance. Calling:
// We have 1 Box named b
Box b;
b.setHeight(5);
b.setWidth(3);
b.setDepth(3);
//ClassName::StaticVariable;
int c1 = Box::count; // returns 1
//ClassName::StaticFunction(Parameters);
int c2 = Box::getCount(); // returns 1

When you declare a function (a method) in a class, this method can be called on a instance of this class (a object).
In the given code the function Complex sum (Complex c1, Complex c2); should be called on an object of type Complex.
But as the function doesn't change anything inside the object, it rather creates a new object and returns it, you should better declare a static method.
static Complex sum(Complex, Complex);
in this case you can call the function without an existing Complex object.
The syntax is the following :
r = Complex::sum(a, b);

Related

I am having problem with the error class undeclared in scope

I am compiling these programs. Complex.h, Complex.cpp, and project1_task1.cpp on centOS I compile this fine in visual studio, but I get the error in centOS. this is for a class.
Complex.h
#ifndef COMPLEX_H
#define COMPLEX_H
class Complex
{
private:
double realPart;
double imaginaryPart;
public:
Complex(double real = 0, double imag = 0); //constructor that initializes the complex number by default arguments
double getReal(); //get function that returns the real part of the complex number
double getImag(); //get function that returns the imaginary part of the complex number
void setReal(double real); //set function that sets the real part of the complex number
void setImag(double imag); //set function that sets the imaginary part of the complex number
void print(); //function that displays the complex number
};
#endif
Complex.cpp
#include <iostream>
#include "Complex.h"
using namespace std;
Complex::Complex(double real, double imag)
{
realPart = real;
imaginaryPart = imag;
}
double Complex::getReal() {
return this->realPart;
}
double Complex::getImag() {
return this->imaginaryPart;
}
void Complex::setReal(double real) {
realPart = real;
}
void Complex::setImag(double imag) {
imaginaryPart = imag;
}
void Complex::print() {
if (realPart != 0)
cout << realPart;
if (imaginaryPart != 0)
{
if (imaginaryPart == 1)
cout << "+i";
else if (imaginaryPart == -1)
cout << "-i";
else if (imaginaryPart > 0 && realPart != 0)
cout << " + " << imaginaryPart << "i";
else
cout << imaginaryPart << "i";
}
cout << endl;
}
here is project1_task1.cpp
#include <iostream>
#include"complex.h"
using namespace std;
int main()
{
Complex c;
c.setReal(2);
c.setImag(3);
c.print();
Complex c1(4);
c1.setImag(5);
c1.print();
Complex c2(6, 7);
c2.print();
return 0;
}
I keep getting Complex not defined in project1_task1.cpp when I compile in centOs.
how can I fix this?
Since linux filesystem are usually case sensitive, then do in
project1_task1.cpp
replace the
#include"complex.h"
with
#include"Complex.h"

C++ - How can we call a class without calling its attributes?

I need to implement the class Multiplier for a school exercise, but I do not understand how the teacher was able to call prod() without calling its inputs.
The goal of the code is to read a sequence of integers until the product of their absolute values is greater than 200.
Can somebody help me understanding please?
Here is the code:
#include <iostream>
using namespace std;
int main()
{
Product mult(200);
cout << "Enter numbers: " << endl;
do{
cin >> mult;
} while(!mult.exceed_limit());
cout << "The absolute values product is " << mult() << " . " << endl;
return 0;
}
A class can implement the "call" operation by overloading the operator() member function.
For example
class MyType {
public:
void operator()(int param) const {
std::cout << "MyType(int) called with: " << param << "\n";
}
void operator()() const {
std::cout << "MyType() called\n";
}
};
int main() {
MyType instance;
instance(12);
instance();
return 0;
}
Multiplier prod(100); - Multiplier must have defined a constructor that takes an integer as input, eg:
class Multiplier
{
...
public:
Multiplier(int value);
...
};
cin >> prod - Multiplier must have overloaded operator>> for input, eg:
class Multiplier
{
...
};
istream& operator>>(istream&, Multiplier&);
prod.limit_exceeded() - Multiplier must have defined a member limit_exceeded() method, eg:
class Multiplier
{
...
public:
bool limit_exceeded() const;
...
};
cout << prod() - Multiplier must have overloaded operator() (and the return value is then streamed to cout via operator<<), eg:
class Multiplier
{
...
public:
int operator()() const;
...
};
Lets see what we need
int main()
{
Multiplier prod(3);
A constructor. The parameter is probably the number of factors to be multiplied.
std::cout << "Enter numbers: " << std::endl;
do{
std::cin >> prod;
A way to "input" the factors.
} while(!prod.limit_exceeded());
A method to see if the entered factors equals the number of desired factors.
std::cout << "The product of the absolute values is " << prod() << " . " << std::endl;
A call operator that returns the resulting product.
return 0;
}
So lets do that:
struct Multiplier {
Multiplier(size_t n) : max_factors(n),num_factors(0),product(1) {}
size_t max_factors;
size_t num_factors;
double product;
double operator()() const { return product;}
bool limit_exceeded() const { return max_factors <= num_factors;}
};
Constructor takes number of factors, product holds the result, operator() returns the result and limit_exceeded() checks if all factors have been entered. Finally, a an overload for operator>> to read the factors:
std::istream& operator>>(std::istream& in, Multiplier& m){
double x;
if (in >> x) {
m.product *= x;
++m.num_factors;
}
return in;
}
It is a bit uncommon for std::cin >> prod; to not read prod but instead to modify prod, but thats fine.
Live Demo

swap user input in C++

I wish to create a constructor which takes input value from user, i.e value of a and b and then I wish to use these values in another function swap. This is more of general example. I wish to know where my concept is wrong.
#include <iostream>
using namespace std;
class swap_value
int a,b;
public:
swap_value()
{
cout<<"enter two numbers to swap";
cout<<"value of a is:";
cin>>a;
cout<<"value of b is:";
cin>>b;
}
void swap(int &a,int &b)
{
int temp=a;
a=b;
b=temp;
cout<<"value of a is :"<<a;
cout<<"value of b is :"<<b;
}
};
int main() {
swap_value obj;
obj.swap();
return 0;
}
#include <iostream>
using namespace std;
class swap_value {
int a,b;
public:
swap_value()
{
cout<<"enter two numbers to swap";
cout<<"value of a is:";
cin>>a;
cout<<"value of b is:";
cin>>b;
}
void swap(int &a,int &b)
{
int temp=a;
a=b;
b=temp;
cout<<"value of a is :"<<a;
cout<<"value of b is :"<<b;
}
};
int main() {
swap_value obj;
obj.swap();
return 0;
}
The thing that you should know is that all members of a class are accessible to all the methods of your class. So they don't need to be passed as parameters. The code you wrote doesn't compile (include error messages next time) because SwapValue doesn't have a method called swap() that takes no parameters.
Here is your code that does what you want it to. The change that I made was simply to make SwapValues::swap() take no parameters. Also, it is common practice to use UpperCamelCase for class names in C++. Indeed, it took me more time than it should have to notice that swap_values(){...} was your constructor for that reason.
#include <iostream>
using namespace std;
class SwapValues {
int a,b;
public:
SwapValues()
{
cout<<"enter two numbers to swap";
cout<<"value of a is:";
cin>>a;
cout<<"value of b is:";
cin>>b;
}
void swap()
{
int temp=a;
a=b;
b=temp;
cout<<"value of a is :"<<a << std::endl;
cout<<"value of b is :"<<b << std::endl;
}
};
int main() {
SwapValues sv;
sv.swap();
return 0;
}
Edit
To respond to the follow-up general question underlying the problem, the reason you are confused is because you are not sure about how the function gets access to a and b.
The short version is that methods of a class have built in access to all the attributes of the class.
The long version is that the instance of the class gets implicitly passed to methods of the class as an implicit parameter (called this in C++). So all functions of a class MyClass like
int MyClass::my_function( --parameters-- )
become
int MyClass::my_function(MyClass* this, --parameters--)
and the compiler, when it compiles code of such a function, sees
some_var = 1234;
will check firs if the function has a local variable or a local static variable or a parameter called some_var, and if there isn't, it will see if
this->some_var = 1234;
that is, it will check if `MyClass has an attribute called some_var.
In your case, in the working code we have
int temp = a;
so the compiler looks: is there a local variable called a, no local variable, is there a parameter called a, nope, next, what about this->a, the class does have an attribute called a so that's what we use.
So you always pass parameters, is the answer to your question but in the example of your function, that is done automatically. That's good because if you add an attribute to your class, you don't have to alter all the methods of your class to take an extra parameter, all the methods of the class will already have it.
In your first example, in fact, you should run this piece of code. It will show what I mean.
#include <iostream>
using namespace std;
class SwapValues {
public:
int a,b;
SwapValues()
{
a = 1;
b = 2;
}
void wrong_method(int &a, int &b)
{
std::cout << "wrong_method : "
<< "a = " << a
<< ", b = " << b
<< ", this->a = " << this->a
<< ", this->b = " << this->b << std::endl;
}
void right_method(int &param_1, int& param_2)
{
std::cout << "right_method : " << "a = " << a
<< ", b = " << b
<< ", param_1 = " << param_1
<< ", param_2 = " << param_2 << std::endl;
}
};
int main() {
SwapValues sv;
int c = 3;
int d = 4;
sv.wrong_method(c,d);
sv.right_method(c,d);
return 0;
}
Gives
wrong_method : a = 3, b = 4, this->a = 1, this->b = 2
right_method : a = 1, b = 2, param_1 = 3, param_2 = 4
This should demonstrate what I meant. The right and wrong because the wrong function has a name clash between the parameters and the attributes of the object. It makes errors possible and reflects bad design.
#include <iostream>
using namespace std;
class swap_value
{
private:
int a;
int b;
public:
swap_value()
{
cout<<"enter two numbers to swap";
cout<<"value of a is:";
cin>>a;
cout<<"value of b is:";
cin>>b;
}
void swap()
{
int temp=a;
a=b;
b=temp;
cout<<"value of a is :"<<a;
cout<<"value of b is :"<<b;
}
};
int main() {
swap_value obj;
obj.swap();
return 0;
}

Addition of complex numbers using classes

I am trying to add 2 complex numbers together, but i am getting the errors:
no operator "+" matches these operands
no operator "<<" matches these operands
#include <iostream>
using namespace std;
class complex
{
public:
double get_r() { return r; }
void set_r(double newr) { r=newr; }
double set_i() { return i; }
void set_i(double newi) { i = newi; }
private:
double r, i;
};
int main()
{
complex A, B;
A.set_r(1.0);
A.set_i(2.0);
B.set_r(3.0);
B.set_i(2.0);
complex sum = A+B;
cout << "summen er: " << sum << endl;
system("PAUSE");
return 0;
};
I'm very new to programming, but i can't see why it won't add these numbers together. What have I done wrong?
You must overload operators + and << (and each one in your need) for your defined classes. Note that operators are no more than specific functions with specific definition syntax (operator+, for example: C = A + B could be understood as C = A.sum(B)). Here a link about http://en.cppreference.com/w/cpp/language/operators
Operator + is defined for builtin types and for some types from the standard library. As complex is here a custom class, you must define all operators that should act on it.
operator + could be defined as:
class complex {
...
complex operator + (const complex& other) {
return complex(get_r() + other.get_r(), get_i() + other.get_i());
}
...
};
Beware that does allow neither A++ nor A-B. They would require (resp.) complex & operator ++() or complex operator - (const complex &).
For stream insertion, the first parameter is the stream itself, so you must define a friend operator with 2 parameters outside the class:
outstream& opererator << (outstream &out, const complex& val) {
// output it the way you want
return out;
}
Complex numbers are part of the C++ standard. Here is the example from http://en.cppreference.com/w/cpp/numeric/complex.
#include <iostream>
#include <iomanip>
#include <complex>
#include <cmath>
int main()
{
using namespace std::complex_literals;
std::cout << std::fixed << std::setprecision(1);
std::complex<double> z1 = 1i * 1i;
std::cout << "i * i = " << z1 << '\n';
std::complex<double> z2 = std::pow(1i, 2);
std::cout << "pow(i, 2) = " << z2 << '\n';
double PI = std::acos(-1);
std::complex<double> z3 = std::exp(1i * PI);
std::cout << "exp(i * pi) = " << z3 << '\n';
std::complex<double> z4 = 1. + 2i, z5 = 1. - 2i;
std::cout << "(1+2i)*(1-2i) = " << z4*z5 << '\n';
}
Trying to implement a class complex yourself would require you define addition, equality, and ostream. And you would only have 5% of a fully implemented class. Looking at the header itself will reveal how those that wrote the C++ standard library implemented the whole thing.
All the arithmetic operators like plus, minus, multiply or divide only work with pre defined data types, like int, char, float etc.
Now if you want to add something in a class, you have to use the fundamental aspect of OO programming that is operator overloading.
Here is how you can achieve it.
#include <iostream>
using namespace std;
class complex
{
float x, y;
public:
complex()
{
}
complex(float real, float img)
{
x = real;
y = img;
}
friend complex operator+(complex,complex);
void display(void);
};
complex operator+(complex c,complex d)
{
complex t;
t.x = d.x + c.x;
t.y = d.y + t.y;
return(t);
};
void complex::display(void)
{
cout << x << "+i" << y << endl;
}
int main()
{
complex c1, c2, c3;
c1 = complex(2.5, 3.5);
c2 = complex(1.5, 5.5);
c3 = c1 + c2;//c3=opra+(c1,c2)
cout << "C1:" << endl;
c1.display();
cout << "C2:" << endl;
c2.display();
cout << "C3:" << endl;
c3.display();
}

C++ not modifiable lvalue

When I run this code, I get the an error saying C.getRadius() isn't modifiable lvalue:
#include <iostream>
#include <conio.h>
using namespace std;
class Circle {
double x, y, r;
public:
Circle (double a=1.0, double b=1.0, double c=1.0) { x=a; y=b; r=c; }
~Circle() {}
double Area();
double getRadius();
};
class Conus {
double height;
Circle C;
public:
Conus (double , double , double , double );
~Conus() {};
double Volume();
void setRadius(double );
};
Conus::Conus(double h, double a, double b, double c)
: C (a, b, c)
{
height=h;
}
double Circle::Area() { return r*r*3.14; }
double Conus::Volume() { return C.Area()*height; }
double Circle::getRadius() { return r; }
void Conus::setRadius(double t ) { C.getRadius()=t; }
int main() {
double a=2.4, b=3.5, r=5.4, h=5.9;
Circle Wre (a, b, r) ;
Conus Konusi (h, a, b, r) ;
cout << "Wris centris koordinatebia: " << a << " da " << b << ", radiusi: " << r
<< ". Wris fartobia :" << Wre.Area() << endl;
cout << "Konusis fudzis centris koordinatebia: " << a << " da " << b << ", radiusi: " << r
<<endl<< "konusis moculobaa: " << Konusi.Volume() << endl;
Konusi.setRadius(r+3);
cout << Konusi.Volume() << endl;
_getch();
return 0;
}
getRadius() returns a copy of the object's radius, not a reference to it, so you can't use it for modification. So the following expression:
C.getRadius()=t;
attempts to modify a temporary copy, which isn't allowed. (The reason that its not allowed is that otherwise that code would compile but do nothing useful, giving a subtle bug rather than an easily identified compile error).
There are various options:
return a reference, double & getRadius();
add a void setRadius(double); function, and use that for modification
make the radius public; there's little point in using accessors unless they're necessary to enforce invariants.
If you do want accessor functions, you should keep the existing double getRadius(), but declare it const. That will allow you to get, but not modify, the radius of a constant object.
This is a not a correct assignment, you are attempting to modify a temporary copy of the r not r itself:
C.getRadius()=t;
One way to fix this would be to add this method to Circle:
void setRadius( double t ){ r = t ; }
and call like:
void Conus::setRadius(double t ) { C.setRadius( t ); }
this is a great article Understanding lvalues and rvalues in C and C++ and the first example is similar to the problem you were facing just now.