Main function of complex number class C++ - c++

I am working on an assignment for C++, I am very new to this language. The assignment is about implementing Newton Raphson Method for a function with complex roots. I have implemented the code.
I want to test my code now and I am having difficulty in getting my main function to work properly, there are some concepts I am not understanding that lead to my wrong implementation. I would appreciate some explanations so I can understand better. Thanks.
This is the example of my code:
Complex.h
#include<iostream>
#include<cmath>
using namespace std;
class Complex {
private:
double r;
double i;
public:
Complex(double real, double imaginary);
friend Complex operator+(const Complex& c1, const Complex& c2);
friend ostream& operator<<(ostream& outs, const Complex& number);
};
Complex.cpp
#include "testComplex.h"
Complex::Complex(double real = 0.0, double imaginary = 0.0) : r(real), i(imaginary) {}
Complex operator+(const Complex& c1, const Complex& c2) {
Complex result;
result.r = c1.r + c2.r;
result.i = c1.i + c2.i;
return result;
}
main.cpp
#include <iostream>
#include "testComplex.h"
using namespace std;
int main () {
Complex x;
Complex y;
Complex sum;
x = Complex(2, 4);
y = Complex(3, 0);
sum = x + y;
cout << "The sum (x + y) is: " << sum << endl;
return 0;
}
This is a part of the error that I am receiving:
testComplexmain.cc: In function ‘int main()’:
testComplexmain.cc:8:10: error: no matching function for call to ‘Complex::Complex()’
testComplexmain.cc:8:10: note: candidates are:
testComplex.h:15:2: note: Complex::Complex(double, double)
testComplex.h:15:2: note: candidate expects 2 arguments, 0 provided
testComplex.h:8:7: note: Complex::Complex(const Complex&)
testComplex.h:8:7: note: candidate expects 1 argument, 0 provided
testComplexmain.cc:9:10: error: no matching function for call to ‘Complex::Complex()’

You don't have a default constructor. The two-argument constructor could be used as one, since both arguments are optional; but you'll have to put the default arguments on the declaration in the header, not the definition in the source file, for them to be usable from main.
Personally, I'd use std::complex rather than reinventing it.

You don't have a default constructor because you put the default parameters in the definition, so you can only construct Complex instances by passing two parameters.
You could add a default constructor,
Complex() : r(0), i(0) {}
or put the default parameters in the function declaration instead of in the definition
Complex(double real = 0.0, double imaginary = 0.0);
or write your code like this:
int main () {
Complex x(2, 4);
Complex y(3, 0);
Complex sum = x + y;
cout << "The sum (x + y) is: " << sum << endl;
return 0;
}

Related

Why Class C++ can be equal to a variable

I have this code:
#include <iostream>
using namespace std;
class complex
{
double re;
double im;
public:
complex(): re(0), im(0) {}
complex(double x) {re = x, im = x;}
complex(double x, double y) {re=x, im =y;}
void print() {cout << re << " " << im;}
};
int main()
{
complex c1;
double i=2;
c1 = i;
c1.print();
return 0;
}
My question is, why the code in this line compiles.
c1 = i;
The compiler gives no error(or warning), why?
Let's examine what happens in the line.
c1 = i;
What happens is that operator= is called for class complex, which, in this case, is implicitly defined.
/////////////////////////////////////
//implicit copy assignment operator//
/////////////////////////////////////
complex& operator=(const complex& cmp)
{
//the default implicit function of this operator is copying every member of cmp into this.
}
So it takes const complex& as argument, which can be bound to rvalue of type complex, then the compiler searches to see if there is a constructor accepting double parameter, so the expression is resolved into.
c1 = complex(i);
Which, obviously, can be executed.
c1 = i invokes the constructor complex(double x) {re = x, im = x;}. If you'd prefer it didn't you can specify the constructor as explicit, like so:
explicit complex(double x) {re = x, im = x;}
Then the compiler would issue an error # c1 = i;
Because your constructor isn't explicit.
A constructor with a single non-default parameter (until C++11) that is declared without the function specifier explicit is called a converting constructor.
So having a constructor with a single non-default parameter, such as your complex(double x) will enable you to write complex s = 5.0 and call said constructor.
I have added some comments that explain how this program works. When you write c1 = i; then a temporary of type complex will be created using the converting constructor and then that temporary will be assigned to c1 using the assignment operator.
#include <iostream>
using namespace std;
class complex
{
double re;
double im;
public:
complex(): re(0), im(0){}
//this converting constructor will be used to create a temporary of type complex from variable i
complex(double x)
{
std::cout<<"single parameter constructor used"<<std::endl;
re = x;
im = x;
}
complex(double x, double y) {re=x, im =y;}
void print() {cout << re << " " << im;}
//this assignment operator = will be used to assign the temporary(of type complex) created above to variable c1
complex& operator=(const complex &rhs)
{
std::cout<<"assignment operator used"<<std::endl;
}
complex(const complex&)
{
std::cout<<"copy constructor used"<<std::endl;
}
};
int main()
{
complex c1;
double i=2;
c1 = i;//first a temporary of type complex will be created using the converting constructor and then that temporary will be assigned to c1 using the assignment operator=
c1.print();
return 0;
}
If you want to prevent this kind of usage, you can make the converting constructor explicit by adding the keyword explicit in front of the converting constructor.

Cannot call member function without object (though I believe I did initialize it)

Hi I'm trying to define my own sqrt func for my complex number class and call it in My_code namespace, which is brought about in the global main method.
When I try to compile and run the code, the
auto z2 = complex::sqrt(z);
doesn't go through the compiler.
I've tried printing my initialized complex number z, which works perfectly fine. I've also tried other functions like overloaded operators on z, and they also work fine. I am not sure where my problem lies.
//defining a new complex class and a function using your own namespace
#include <cmath>
#include <utility>
#include <iostream>
namespace My_code{
class complex{
double re, im;
public:
complex(double r, double i): re(r), im(i) {}
complex(double r): re(r), im(0) {}
complex() : re(0), im(0) {}
double real() const { return re; }
double imag() const { return im; }
complex& operator += (complex z){
re += z.re;
im += z.im;
return *this;
}
complex& operator -= (complex z){
re -= z.re;
im -= z.im;
return *this;
}
auto sqrt(const complex& number);
};
auto complex::sqrt(const complex& number){
auto re = number.real();
auto im = number.imag();
auto modulus = std::sqrt(re*re + im*im);
auto x_sq = (re + modulus)/2;
auto y_sq = modulus - x_sq;
if(im < 0){
//x & y are of opposite signs
auto value = std::make_pair(complex(std::sqrt(x_sq), - std::sqrt(y_sq) ), complex(-std::sqrt(x_sq), std::sqrt(y_sq))); //tuple
return value;}
else{
//x&y are of same signs
auto value = std::make_pair(complex(std::sqrt(x_sq), std::sqrt(y_sq)), complex(-std::sqrt(x_sq), -std::sqrt(y_sq))); //tuple
return value;}
}
int main();
}
int My_code:: main(){
complex z {8, -6};
auto z2 = complex::sqrt(z);
//auto z3 = z2.first;
//std::cout << '{' << z3.real() << ',' << z3.imag() << "}\n";
std::cout << '{' << z.real() << ',' << z.imag() << "}\n";
return 0;
}
int main(){
My_code::main();
return 0;
}
I expect my complex sqrt func to give me a pair of complex numbers that is (3, -1) & (-3, 1).
Cannot call member function without object
Correct. You can only call non-static member functions using a member access operator. Member access operator requires an object as the left hand argument.
You can call your sqrt function like this for example:
complex z1 {8, -6};
complex z2 {8, -6};
auto z3 = z1.sqrt(z2);
That said, you never use members of the left hand argument, so it is unclear why you've declared the function to be a non-static member function. You may intended to declare a static member function instead. Static member functions can be called without member access operator, using exactly the syntax that you attempted to use with the non-static member function.

Using an overloaded operator+ within a function template in C++

This is for a school assignment. I am supposed to adhere to the requirement to use an overloaded operator and it has to be called within the function template called "increase".
This is a class called Inductor.
#pragma once
#include <iostream>
using namespace std;
class Inductor {
friend ostream& operator<<(ostream&, Inductor);
private:
int inductance;
double maxCurrent;
public:
int operator+(int add);
int operator-(int sub);
Inductor(int, double);
};
Inductor::Inductor(int x, double y)
{
inductance = x;
maxCurrent = y;
}
int Inductor::operator+(int add)
{
int newSum = inductance + add;
return newSum;
}
int Inductor::operator-(int sub)
{
int newDiff = inductance - sub;
return newDiff;
}
ostream& operator<<(ostream& out, Inductor inductor)
{
out << "Inductor parameters: " << inductor.inductance << ", " << inductor.maxCurrent << endl;
return out;
}
While this is my function template "increase".
template<class FIRST>
FIRST increase(FIRST a, int b) {
FIRST c;
c = a + b;
return c;
}
Last but not least, my main file:
int main()
{
Inductor ind(450, 0.5);
ind = increase(ind, 70);
}
These are the following compilation errors which I do not understand:
error C2512: 'Inductor': no appropriate default constructor available
error C2679: binary '=': no operator found which takes a right-hand operand of type 'int' (or there is no acceptable conversion)
note: could be 'Inductor &Inductor::operator =(Inductor &&)'
note: or 'Inductor &Inductor::operator =(const Inductor &)'
note: see reference to function template instantiation 'FIRST increase<Inductor>(FIRST,int)' being compiled
with
[
FIRST=Inductor
]
note: see declaration of 'Inductor'
Can anyone care to explain why is the compiler throwing these errors? Yes I have googled and searched through StackOverflow, but I do not see an article where an overloaded operator+ from a class is being used within a function template.
template<class FIRST>
FIRST increase(FIRST a, int b) {
FIRST c;
c = a + b;
return c;
}
with FIRST == Inductor has several problems:
FIRST c;: You try to create Inductor whereas there is no default constructor.
c = a + b;: You try to assign to Inductor an int (return type of your operator +), and there is no such operator. and as there is no constructor taking only int to build Inductor, copy assignment is not an alternative.
The first error is easy to fix, just get rid of the variable (return a + b;) or initialize it directly (FIRST c = a + b; return c;).
For the second error, add a (non explicit) constructor taking only an int or change your operator+ to return Inductor directly:
Inductor Inductor::operator+(int add)
{
return Inductor(inductance + add, maxCurrent);
}

Default parameters are not of the same type?

I posted earlier about a problem with my constructor, I fixed it somehow. Now I am getting an error when I am trying to declare an object of type 'Rational' with userinput and another with default paramaters. When I try to use my overload operators, it gives me this error.
error: no match for 'operator+' (operand types are 'Rational()' and 'Rational')
Rational xxx = test6+test5;
My .H files
#ifndef RATIONAL_H
#define RATIONAL_H
#include <iostream>
#include <stdexcept>
using namespace std;
class Rational {
private:
int num, denom;
public:
/* Set Numerator and Denom */
Rational(int nu, int deno);
int gcd(int x, int y);
Rational operator+(const Rational& other);
Rational operator-(const Rational& other);
Rational operator*(const Rational& other);
Rational operator/(const Rational& other);
friend ostream &operator<<(ostream& os, const Rational& rat);
void deci();
};
#endif
This is my .cpp file
#include "Rational2.h"
#include <iostream>
#include <stdexcept>
using namespace std;
int Rational::gcd(int x, int y) {
while (y != 0) {
int r(x % y); // compute remainder
x = y;
y = r;
}
return x;
}
Rational::Rational(int nu =1, int deno =1){
if (deno == 0){
cout << "Denominator Can't Be 0" << endl;
}else{
num = nu/gcd(nu, deno);
denom = deno/gcd(nu, deno);
}
}
Rational Rational::operator+(const Rational & other){
int nn = num*other.denom + denom*other.num;
int dd = denom * other.denom;
return Rational(nn, dd);
}
Test Main File
Rational test5(3,4)
Rational test6();
Rational xxx = test6+test5;
cout << xxx << endl;
So it should add normally,
3/4 + 1/1, where 1/1 would be my default parameters if user does not input anything when calling an object of rational type
I am not sure if it is a problem with the default parameter from the constructor, or my operator+ method does not contain an option to add default parameters?
It should just treat the two objects of the same type
UPDATE:
After removing the parentheses, I get this error
main.cpp:32:11: error: no matching function for call to 'Rational::Rational()'
Rational test6;
^
main.cpp:32:11: note: candidates are:
In file included from main.cpp:2:0:
Rational2.h:13:2: note: Rational::Rational(int, int)
Rational(int nu, int deno);
^
Rational2.h:13:2: note: candidate expects 2 arguments, 0 provided
Rational2.h:8:7: note: Rational::Rational(const Rational&)
class Rational {
^
Rational2.h:8:7: note: candidate expects 1 argument, 0 provided
Am I suppose to create another method just declaring Rational without the parentheses in my cpp?
Your line Rational test6(); is not defining a new variable of type Rational, it's defining a function called test6 that returns Rational, taking in no parameters. To get the behaviour you want, remove the parentheses: Rational test6;
Or, if you're using C++11 I believe you can use curly braces: Rational test6{};
After the Update:
You've told us your default parameters are 1/1, but you have to tell the compiler, too.
You need to either put default values on your existing constructor, or provide a default constructor.
Rational test6();
Believe it, or not, but this gets parsed as a declaration of a function named test6() that returns an instance of Rational.
Things pretty much fall apart to pieces, from that point on.
Change this to:
Rational test6;
P.S.: you do actually have a small problem with your operator overload. It should really be:
Rational Rational::operator+(const Rational &other)

Polymorphic plus sign in C++?

I understand how polymorphism and inheritance works in C++, but my problem is: how do you make operators polymorphic for the following specific example?
Say I have a Foo class and two Foo instances, fooA and fooB. I want to redefine the plus sign operator so that "fooA + fooB;" does something specific to Foo instances (whatever that may be). How would the function prototype look? It's confusing me because I'm used to functions starting with a letter... Any help would be greatly appreciated.
By the way, this isn't a homework question -- more like a wonderment (I was thinking about polymorphism in Ruby).
Example from http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/topic/com.ibm.xlcpp8a.doc/language/ref/cplr318.htm:
#include <iostream>
using namespace std;
class complx
{
double real, imag;
public:
complx(double real = 0., double imag = 0.); // constructor
complx operator+(const complx&) const; // operator+()
};
// define constructor
complx::complx(double r, double i)
{
real = r; imag = i;
}
// define overloaded + (plus) operator
complx complx::operator+(const complx& c) const
{
complx result;
result.real = this->real + c.real;
result.imag = this->imag + c.imag;
return result;
}
int main()
{
complx x(4,4);
complx y(6,6);
complx z = x + y; // calls complx::operator+()
}
const Foo operator+(const Foo& a, const Foo& b) is the correct signature. It will need to be a friend function if the data is private and has no mutator functions (that is, "setters").
Operators should be global functions instead of members in order for the the first parameter to be coerced to your type. For example, if int can be coerced to Foo, this is legal with the above signature: 1 + foo.
Edit:
Code demonstrating why operator+ should be global...
struct Foo {
int i;
Foo(int i) : i(i) {}
const Foo operator+(const Foo& a) {
return Foo(this->i + a.i);
}
};
int main() {
Foo f(5);
f + 1;
1 + f; // g++ 4.5 gacks here.
return 0;
}
Here's the error:
main.cpp: In function ‘int main()’:
main.cpp:14:9: error: no match for ‘operator+’ in ‘1 + f’
For binary +, you need some form of double dispatch, which isn't
supported out of the box by C++. There are several ways of implementing
this, all with various disadvantages. And regardless of how you
implement the double dispatch itself, for n different derived types,
you will need n2 different functions.