Errors when compiling complex number class in c++ - c++

I have code that is supposed to show addition, subtraction, etc. of complex numbers with no input from the user necessary. I have three classes: test.cpp, complex.cpp, and complex.h to run the program, define the constructors and methods, and create a header class respectively. However, when I run my code I get a series of errors that I've been trying to figure out for a while now.
complex.h
//complex class definition
#ifndef COMPLEX_H
#define COMPLEX_H
//class complex
class Complex
{
public:
Complex(); //default no arg constructor
Complex(double a); //one arg constructor
Complex(double a, double b); //two arg constructor
Complex operator+(const Complex &) const; //addition method
Complex operator-(const Complex &) const; //subtraction method
Complex operator*(const Complex &) const; //multiplication method
Complex operator/(const Complex &) const; //division method
void print() const; //output
private:
double a; //real number
double b; //imaginary number
}; //end class Complex
#endif
complex.cpp
#include "stdafx.h"
#include <iostream>
#include "complex.h"
using namespace std;
//no arg constructor
Complex::Complex()
{
a = 0;
b = 0;
}
//one arg instructor
Complex::Complex(double real)
{
a = real;
b = 0;
}
//two arg constructor
Complex::Complex(double real, double imaginary)
{
a = real;
b = imaginary;
}
//addition
Complex Complex::operator+(const Complex &number2) const
{
return a + number2.a, b + number2.b;
}
//subtraction
Complex Complex::operator-(const Complex &number2) const
{
return a - number2.a, b - number2.b;
}
//multiplication
Complex Complex::operator*(const Complex &number2) const
{
return a * number2.a, b * number2.b;
}
//division
Complex Complex::operator/(const Complex &number2) const
{
return a / number2.a, b / number2.b;
}
//output display for complex number
void Complex::print() const
{
cout << '(' << a << ", " << b << ')';
}
test.cpp
#include <iostream>
#include <complex>
#include "complex.h"
#include "stdafx.h"
using namespace std;
int main()
{
Complex b(1.0, 0.0);
Complex c(3.0, -1.0);
/*cout << "a: ";
a.print();
system ("PAUSE");*/
};
In test right now as the code shows the lower parts are commented out and I have attempted to only call two of the three constructors to see if I can get any of this working.
The errors I receive:
error C2065: 'Complex' : undeclared identifier
error C2065: 'Complex' : undeclared identifier
error C2146: syntax error : missing ';' before identifier 'b'
error C2146: syntax error : missing ';' before identifier 'c'
error C3861: 'b': identifier not found
error C3861: 'c': identifier not found
I am trying to run this in Visual Studio 2010. Can someone please help?

I think the problem is in your Complex.cpp. If there are errors compiling the code of the class, the class is unknown and so the identifier Complex, too.
After a quick view, everthing seem to be correct but your operator functions have some errors:
Incorrect:
//addition
Complex Complex::operator+(const Complex &number2) const
{
return a + number2.a, b + number2.b;
}
Correct:
//addition
Complex Complex::operator+(const Complex &number2) const
{
return Complex(a + number2.a, b + number2.b);
}
The problems are the return types of your operator methods. They have to be the same as declared. Also you cannot return two variables at the same time. If you want to do so, you have to use structs or classes (by calling the constructor of your class Complex with the new values).
If you want to manipulate the members a and b, you cannot define the methods as "const". If you say a function is const, it means all class members values won't be manipulated by calling this method.

You may facing a problem with stdafx.h issue
At least you should try to put #include "stdafx.h before every other include
Or
you could try to set your project property to not use stdafx.h
1. right click on project and select Properties
2. go to C/C++ -> Precompiled Headers
3. select "Not Using Precompiled Headers"

#include <complex>
#include "complex.h"
That's a bad smell. It's possible that both those #include files use the same name for the header guard.
Try changing yours like this.
#ifndef MY_COMPLEX_H
#define MY_COMPLEX_H
.. And maybe rename your module from "complex" to something else, to avoid clashes with the system header file of the same name.

Try making it as simple as possible. Then add parts back until you find your error.
Does this work?
#include "complex.h"
int main()
{
Complex c(3.0, -1.0);
return 0;
};

Related

C++ code generating errors LNK2005 & LNK1169 on VS2019

The following code generates errors LNK2005 & LNK1169 on Visual Studio 2019.
LNK2005: "void__cdecl OverloadingPlus(void)" (?OverloadingPlus##YAXXZ) already defined in main.obj
LNK1169: one or more multiply defined symbols found
I reached this point by following a course on Udemy, where the instructor seems to have no problems with it.
Similar questions seem to be related to using global variables, defining functions in the header file, not using #ifndef guards... but as far as I can tell, that doesn't seem to be the case.
This problem started appearing only after the operator+ overload was included, but the operator<< doesn't trigger any errors, even though they have been declared and defined in the same manner.
Interestingly enough, if I remove any reference to OverloadingPlus.h file, and add #include Complex.h to main.cpp, the problem goes away.
I fail to see how including Complex.h in OverloadingPlus.h is contributing to a multiple definition of the operator+ exclusively, even though it is only included once in the entire project and the definitions are implemented in Complex.cpp and not in the header file, as pointed out in answers to similar problems.
Also tried surrounding the content of OverloadingPlus.h with an #ifndef statement just to make sure it is only used once which did not change a thing.
I attempted to declare a diferent operator+ overload inside the class (you can see it commented out), but it produces the same errors.
Commented all references to any other files trying to make sure Complex definitions are only included once. Didn't help either.
The code is the following:
main.cpp
//#include "OverloadingAssignmentOperator.h"
//#include "OverloadingLeftBitShiftOperator.h"
//#include "ComplexNumberClass.h"
#include "OverloadingPlus.h"
int main() {
//OverloadingAssignmentOperator();
//OverloadingLeftBitShiftOperator();
//ComplexNumberClass();
OverloadingPlus();
return 0;
}
OverloadingPlus.h
#ifndef OVERLOADING_PLUS_H
#define OVERLOADING_PLUS_H
#include "Complex.hpp"
using namespace complex;
void OverloadingPlus() {
Complex c1(1, 4);
Complex c2(3, 2);
std::cout << c1 + c2 << std::endl;
}
#endif
Complex.hpp
#ifndef COMPLEX_HPP
#define COMPLEX_HPP
#include <iostream>
namespace complex {
class Complex {
private:
double real;
double imaginary;
public:
Complex();
Complex(double, double);
Complex(const Complex&);
const Complex& operator=(const Complex& other);
//const Complex operator+(const Complex& r);
double getReal() const { return real; }
double getImaginary() const { return imaginary; }
};
Complex operator+(const Complex& l, const Complex& r);
std::ostream& operator<<(std::ostream& out, const Complex& c);
}
#endif // !__COMPLEX_HPP__
Complex.cpp
#include "Complex.hpp"
namespace complex {
Complex::Complex() : real(0), imaginary(0) {}
Complex::Complex(double r, double i) : real(r), imaginary(i) {}
Complex::Complex(const Complex& other) {
std::cout << "Copy constructor..." << std::endl;
real = other.real;
imaginary = other.imaginary;
}
const Complex& Complex::operator=(const Complex& other) {
real = other.real;
imaginary = other.imaginary;
return *this;
}
//const Complex Complex::operator+(const Complex& r) {
// return Complex(real + r.getReal(), imaginary + r.getImaginary());
//}
//
Complex operator+(const Complex& l, const Complex& r) {
return Complex(l.getReal()+r.getReal(), l.getImaginary()+r.getImaginary());
}
std::ostream& operator<<(std::ostream& out, const Complex& c) {
out << "(" << c.getReal() << "," << c.getImaginary() << ")";
return out;
}
}
The issue seems to be related to VS2019. Renaming the file to something different, rebuilding the project and renaming the file back to its original name fixed the issue.
While using inline as others suggested did circumvent the issue, it does not solve this specific problem as the conflicting file was not being included multiple times.
You forgot to "inline" your OverloadingPlus.
inline void OverloadingPlus() {
Complex c1(1, 4);
Complex c2(3, 2);
std::cout << c1 + c2 << std::endl;
}
should make the linker error go away.
What probably happened is: You have included "OverloadingPlus.h" in more than one compilation unit (although you failed to provide all instances of your #include in your question).
Every time you include "OverloadingPlus.h" in one of your .cpp files, you add another definition for void OverloadingPlus to your program. The linker detects this and cannot decide on "the right one" and so gives an error.

Visual Studio 2017: How to make intellisense accept friend conversion constructor from other class?

I am following a book with chapter about conversions from 2008. Compiling on visual studio 2017 C++ project.
In the book there was an example on the use of conversion constructor where classes "complex" and "number" exist and "number" can be converted into "complex" through the use of constructor where class "number" befriends the constructor of class "complex" to let it use "number" private properties (as much as I understand).
And the code sample from the book (copied word to word) makes intellisense not happy as it doesn't see friend "complex(number)" constructor and I do not know why.
Code is as below:
#include <string>
class number;
class complex;
int main()
{
return 0;
}
class complex
{
private:
double real;
double imaginary;
public:
complex(double r = 0, double i = 0) : real(r), imaginary(i) {}
complex(number);
};
class number
{
double n;
std::string description;
//friend complex::complex(number); // finds no instance of overload of function complex::complex
public:
number(int k, std::string t = "no description") : n(k), description(t) {}
};
complex::complex(number ob)
{
//real = ob.n; //no friend, no access to private property
imaginary = 0;
}
My question is, why is "friend complex::complex(number);" not visible by intellisense ?
Image of error from the IDE
You can think of this as a bug in intellisense itself. But you can work around it by hiding the code in question. For example,
#ifdef __INTELLISENSE__
#define INTELLIHIDE(...) // Hide from IntelliSense
#else
#define INTELLIHIDE(...) __VA_ARGS__
#endif
So, then you could do this:
INTELLIHIDE(friend complex::complex(number);)
And also,
complex::complex(number ob)
{
INTELLIHIDE(real = ob.n;)
imaginary = 0;
}

Visual Studio 2010 list copy construct throwing C2664 error

SOLVED: Restarted Visual Studio
I'm working on a project for school involving the STL list. and getting this error with xmemory. I'm just trying to build the solution at this point, butxmemory is killing me
Error 1 error C2664: 'GroceryStoreItem::GroceryStoreItem(GroceryStoreItem &)' : cannot convert parameter 1 from 'std::string' to 'GroceryStoreItem &' d:\microsoft visual studio 10.0\vc\include\xmemory 208
Here's my header
#include <string>
#include <sstream>
#include<iostream>
#include <iterator>
#include <list>
using namespace std;
//
//*****************************************************************
// USER DEFINED DATA TYPES
//
class GroceryStoreItem
{
friend ostream & operator<< (ostream &out, const GroceryStoreItem &RHS);
public:
GroceryStoreItem();
GroceryStoreItem(string Name, double cost, string location);
GroceryStoreItem(GroceryStoreItem & GroceryStoreItemCCIn);
GroceryStoreItem & operator= (const GroceryStoreItem &RHS);
string ReturnItemName();
string ReturnLocation();
double ReturnCost();
private:
string ItemName;
string Location;
double Cost;
};
and the implementation
#include "Grocery_Item.h"
using namespace std;
//*****************************************************************
// Grocery Item Constructors
//*****************************************************************
GroceryStoreItem::GroceryStoreItem()
{
ItemName = "default";
Location = "aisle 1";
Cost = 0.0;
}
GroceryStoreItem::GroceryStoreItem(string InName, double InCost, string InLocation)
{
ItemName = InName;
Location = InLocation;
if(InCost >= 0.0f)
{
Cost = InCost;
}
else
{
Cost = 0.0f;
}
}
GroceryStoreItem::GroceryStoreItem(GroceryStoreItem & GroceryStoreItemCCIn) //Copy Constructor
{
ItemName=GroceryStoreItemCCIn.ItemName;
Location=GroceryStoreItemCCIn.Location;
Cost=GroceryStoreItemCCIn.Cost;
}
edit
xmemory error in the last line of
template<class _Other>
void construct(pointer _Ptr, _Other&& _Val)
{ // construct object at _Ptr with value _Val
::new ((void _FARQ *)_Ptr) _Ty(_STD forward<_Other>(_Val));
You need to make your copy constructor argument const
GroceryStoreItem::GroceryStoreItem(const GroceryStoreItem& GroceryStoreItemCCIn)
Also it's generally better to use initialisation not assignment in your copy constructor
GroceryStoreItem::GroceryStoreItem(const GroceryStoreItem& rhs) :
ItemName(rhs.ItemName),
Location(rhs.Location),
Cost(rhs.Cost)
{
}
Finally (and this is the most important lesson of all) because you have done the right thing and used std::string internally in your class you don't actually need a copy constructor at all. The compiler generated default will do the right thing anyway. So I would actually delete your copy constructor, this will also fix the error.
Same argument for your assignment operator, delete that too.
I closed Visual Studio, started a new project and pasted my CPPs and Headers into the new project, and it compiled and worked. Not the ideal answer, but it worked.

Friend function can't access class variables and can't understand Namespaces

I thought that friend functions could access class variables as in how I try to do v.x, v.y, v.z in the << function. But it doesn't compile. It says it's unable to resolve identifier at those lines.
Also I'm trying to learn how to use namespaces. Even though I use the namespace vec in the implementation file I still have to include Vector:: before everything so what's the point?
Header file:
#ifndef VECTOR_H
#define VECTOR_H
namespace vec {
class Vector {
private:
double x, y, z;
public:
Vector(double, double, double);
friend std::ostream& operator<<(std::ostream&, const Vector&);
};
}
#endif /* VECTOR_H */
.cpp file:
#include "Vector.h"
#include <iostream>
using namespace vec;
//Constructor
Vector::Vector(double x1 = 0, double y1 = 0, double z1 = 0) {
x = x1;
y = y1;
z = z1;
}
//Have also tried adding vec:: and Vector:: before operator<< here.
std::ostream& operator<<(std::ostream& out, const Vector& v) {
out<<"<"<<v.x<<", "<<v.y<<", "<<v.z<<">";
return out;
}
I believe part of the problem is that your vec.h doesn't have #include <iostream>, so the type std::ostream is unidentified in that file, and since that part is compiled before the vec.cpp main part, it fails to recognise your function.
You also need to put your operator<< into the namespace of vec. After all, you have asked for a friend function within that namespace.
With these two changes, your code compiles with gcc -Wall -Wextra -O2.
Your compile error may relative to below issues:
Default parameter only goes to function declaration not function
definition, you are doing the other way around.
Also, in Vector.cpp you should wrap up your class member function
definitions in namespace instead of calling using directive.
Try:
Vector.h
#include <iostream>
class Vector {
private:
double x, y, z;
public:
Vector(double x1 = 0, double y1 = 0, double z1 = 0);
^^ ^^ ^^
friend std::ostream& operator<<(std::ostream&, const Vector&);
};
Vector.cpp
namespace vec
{
Vector::Vector(double x1, double y1, double z1)
:x(x1), y(y1), z(z1)
{
}
}
The friend std::ostream& operator<< declaration appears in namespace vec, so the definition should be prefixed by vec::. Your comment says you tried that - maybe you got confused by the other error messages billz documents, but you should reinstate vec::operator<< or surround it with namespace vec { ... }.
This creates an error like:
ns.cc: In function `int main()':
ns.cc:26: error: ambiguous overload for 'operator<<' in 'std::cout << w'
ns.cc:19: note: candidates are: std::ostream& operator<<(std::ostream&, const vec::Vec&)
ns.cc:10: note: std::ostream& vec::operator<<(std::ostream&, const vec::Vec&)

Linker Error in c++, It is just a simple class program, I am beginner at c++

#include<iostream>
#include<stdlib.h>
#include"header_complex.h"
using namespace std;
class Complex
{
private:
float real,imag;
public:
Complex(); //default cnstructor
Complex(float, float); //parametrize constructor
void set_real(float);
void set_imag(float);
float get_real();
float get_imag();
void input();
void display();
};
int main()
{
Complex c1; // object creation
c1.display();
c1.input();
c1.display();
return EXIT_SUCCESS;
}
//Functions definations
Complex::Complex(float a=0, float b=0)
{
real = a;
imag = b;
}
void Complex::set_real(float a)
{
a = real;
}
void Complex::set_imag(float a)
{
a = imag;
}
float Complex::get_real()
{
return real;
}
float Complex::get_imag()
{
return imag;
}
void Complex::input(){
cout << "Enter Real part ";
cin >> real;
cout << "Enter Imaginary part " ;
cin >> imag;
}
void Complex::display()
{
cout << "Real part is " << real;
cout << "Imaginary part is " << imag;
}
error LNK2019: unresolved external
symbol "public: __thiscall
Complex::Complex(void)"
(??0Complex##QAE#XZ) referenced in
function _main
Reading and understanding the error message is a very important skill to learn to get ahead. "Unresolved external" is an error message that the linker produces when it sees you using an identifier but cannot find a definition for it in any of the supplied .obj and .lib files.
Complex::Complex(void) is the missing identifier. It is the constructor of the Complex class that doesn't take any arguments. You declared it, you use it, you just didn't write the code for it.
You can get help on a linker or compiler error by selecting the error message in the Error List window and pressing F1.
I don't understand why anyone would describe an error message so vaguely (say, as a "linker error") without copying and pasting the error message. That said, I was able to compile and link your program on Linux by making the following changes:
1) I moved the class definition for Complex into a header file named header_complex.h, since that's what the main program #includes.
2) I added a definition for the default constructor:
Complex::Complex() : real(0), imag(0) {}
3) I added -lstdc++ to the command line:
gcc complex.cpp -lstdc++
By the way, I think you're going to want to modify your display method to add some endls:
cout << "Real part is " << real << endl;
cout << "Imaginary part is " << imag << endl;
You cannot provide default parameters at the function definition; you must do it at function declaration. Instead of declaring two constructors, declare one like
Complex(float a=0, float b=0);
Then in your definition, remove the defaults, so it becomes
Complex::Complex(float a, float b)
Emm... seems you're missing default constructor while being using it:
Complex c1; // here's the error - you have no defined Complex::Complex() {} method