What do these errors mean?
Vector.cpp:13: error: ISO C++ forbids declaration of ‘Vector’ with no type
Vector.cpp:13: error: explicit qualification in declaration of ‘void Vector::Vector(double, double, double)’
The C++ (Line 13 is the Vector::Vector( ...):
#include <iostream>
using namespace std;
namespace Vector
{
Vector::Vector( double x, double y, double z)
{
a = x;
b = y;
c = z;
}
/*
double Vector::dot(const Vector &v) const
{
return (a*v.a)+(b*v.b)+(c*v.c);
}
*/
Vector Vector::operator+(const Vector &v) const
{
Vector v1( a + v.a, b + v.b, c + v.c );
return v1;
}
Vector Vector::operator-(const Vector &v) const
{
Vector v1( a - v.a, b - v.b, c - v.c );
return v1;
}
bool Vector::operator==(const Vector &v) const
{
if( (a == v.a) && (b == v.b) && (c == v.c) )
{
return true;
}
else
{
return false;
}
}
Vector Vector::operator*(const Vector &v) const
{
Vector v1( b*v.c - c*v.b, c*v.a - a*v.c, a*v.b - b*v.a );
return v1;
}
ostream& operator<<(ostream &out, const Vector &v)
{
out << "<" << v.a << ", " << v.b << ", " << v.c << ">";
return out;
}
istream& operator>>(istream &in, Vector &v)
{
in >> v.a;
in >> v.b;
in >> v.c;
return in;
}
/*
double length( Vector v )
{
return sqrt( (v.a*v.a)+(v.b*v.b)+(v.c*v.c) );
}
*/
} // end namespace Vector
The header file:
#ifndef _VECTOR_H
#define _VECTOR_H
#include <cstdlib>
#include <iostream>
using namespace std;
namespace Vector
{
class Vector
{
private:
double a;
double b;
double c;
public:
Vector( double x=0.0, double y=0.0, double z=0.0);
double dot(const Vector &v) const;
Vector operator+(const Vector &v) const;
Vector operator-(const Vector &v) const;
bool operator==(const Vector &v) const;
Vector operator*(const Vector &v) const;
friend ostream& operator<<(ostream &out, const Vector &v);
friend istream& operator>>(istream &in, Vector &v);
}; // end Vector class
double length(Vector v);
} //end namespace Vector
#endif /* _VECTOR_H */
Constructors have no return type, not even void. Just remove the void and you're fine.
Looks like the major problem is that your cpp files didn't include your header file.
Include the header file in the cpp file. Also, the code has some design issues. operator+ should return const Vector and the same case with operator-.
Related
I wanted to make a hash function for a class I am writing and I wanted to make the hash function a friend of the class so that I didn't have to write an unnecessary getter method. To do that I followed the accepted answer in this SO post. But I wanted to be able to insert the objects into either std::unordered_set or boost::unordered_set. So I wrote it like this:
#include <iostream>
#include <unordered_set>
#include <boost/functional/hash.hpp>
#include <boost/unordered_set.hpp>
class Vec;
namespace std { // line [c]
template<>
struct hash<Vec> {
public:
size_t operator()(const Vec &v) const;
};
}
class Vec {
private:
std::vector<int> v;
public:
friend size_t std::hash<Vec>::operator ()(const Vec& v) const; // line [d]
friend bool operator == (const Vec& lhs, const Vec& rhs) { return lhs.v == rhs.v; }
};
namespace std { // line [e]
size_t hash<Vec>::operator()(const Vec &v) const {
return boost::hash<std::vector<int> >()(v.v);
}
}
int main() {
Vec v;
std::unordered_set<Vec> s1; // line [f]
s1.insert(v); // line [g]
boost::unordered_set<Vec> s2; // line [a]
s2.insert(v); // line [b]
}
But I found that I had a long list of errors when trying to compile this. Then when I removed lines [a,b], it compiled and ran as expected. Then, instead of removing lines [a,b], I (1) left them in, (2) removed lines [f,g], and (3) changed lines [c,d,e] to say boost instead of std, again the code would compile properly. Finally, I tried making a duplicate declaration of the hash struct in the boost namespace:
#include <iostream>
#include <unordered_set>
#include <boost/functional/hash.hpp>
#include <boost/unordered_set.hpp>
class Vec;
namespace std {
template<>
struct hash<Vec> {
public:
size_t operator()(const Vec &v) const;
};
}
// new: {
namespace boost {
template<>
struct hash<Vec> {
public:
size_t operator()(const Vec &v) const;
};
}
// }
class Vec {
private:
std::vector<int> v;
public:
friend size_t std::hash<Vec>::operator ()(const Vec& v) const;
// new: {
friend size_t boost::hash<Vec>::operator ()(const Vec& v) const;
// }
friend bool operator == (const Vec& lhs, const Vec& rhs) { return lhs.v == rhs.v; }
};
namespace std {
size_t hash<Vec>::operator()(const Vec &v) const {
return boost::hash<std::vector<int> >()(v.v);
}
}
// new: {
namespace boost {
size_t hash<Vec>::operator()(const Vec &v) const {
return boost::hash<std::vector<int> >()(v.v);
}
}
// }
int main() {
Vec v;
std::unordered_set<Vec> s1;
s1.insert(v);
boost::unordered_set<Vec> s2;
s2.insert(v);
}
My question is: why do I have to make a hash function in both the std and boost namespace to get it to work? I would say that I have an intuition for why, but I would like a very detailed explanation. And I would like any alternative solutions that would fix the fact that there is a lot of duplicate code in the above code segment (but not something like boost::unordered_set<Vec, my_vec_class_hash> because I want it to be "automatic").
You can reduce the clutter a long way, by using Boost's ADL-enabled customization point hash_value:
class Vec {
private:
std::vector<int> v;
friend size_t hash_value(const Vec& v) {
return boost::hash_range(begin(v.v), end(v.v));
}
friend bool operator==(const Vec& lhs, const Vec& rhs) {
return lhs.v == rhs.v;
}
};
In fact, the hash function can be even simpler with return boost::hash_value(v.v); in this case.
This is already enough to make Boost's unordered containers work with your type:
boost::unordered_set<Vec> s2;
s2.insert(v);
Adding std support
That's a non-issue now:
template <> struct std::hash<Vec> : boost::hash<Vec> {};
Live Demo
Live On Coliru
#include <boost/functional/hash.hpp>
#include <boost/unordered_set.hpp>
#include <iostream>
#include <unordered_set>
class Vec {
private:
std::vector<int> v;
friend size_t hash_value(const Vec& v) {
return boost::hash_value(v.v);
//return boost::hash_range(begin(v.v), end(v.v));
}
friend bool operator==(const Vec& lhs, const Vec& rhs) {
return lhs.v == rhs.v;
}
};
template <> struct std::hash<Vec> : boost::hash<Vec> {};
int main() {
Vec v;
std::unordered_set<Vec> s1;
s1.insert(v);
boost::unordered_set<Vec> s2;
s2.insert(v);
}
I am trying to create a program that manipulates with arrays of complex numbers, my program has two classes, class that represents complex numbers and class that represents an array.
Here's the code that i created so far:
Complex.h
#pragma once
#include <functional>
class Complex
{
friend class Array;
double re, im;
friend std::ostream& operator<<(std::ostream&, const Array&);
friend std::istream& operator>>(std::istream&, Array&);
public:
double getRe() const;
double getIm() const;
void setRe(double);
void setIm(double);
Complex operator[](int);
Complex operator=(const Complex&);
Complex operator+(const Complex&);
Complex operator-(const Complex&);
private:
Complex apply(const Complex&, const std::function <double(double, double)> &);
};
Array.h
#pragma once
#include "Complex.h"
#include <functional>
class Array
{
Complex *arr;
int n;
friend std::ostream& operator<<(std::ostream&, const Array&);
friend std::istream& operator>>(std::istream&, Array&);
public:
Array();
Array(int);
Array(const Array&);
Array(Array&&);
~Array();
Array& operator=(const Array&);
Array& operator=(Array &&);
Array operator+(const Array&);
// Array operator-(const Array&);
private:
Array& copy(Array&);
Array& move(Array&);
Array compute(const Array &,const std::function<Complex(Complex, Complex)> &f);
};
Complex.cpp
#include <iostream>
#include "Complex.h"
double Complex::getRe() const
{
return re;
}
double Complex::getIm() const
{
return im;
}
void Complex::setRe(double re)
{
this->re = re;
}
void Complex::setIm(double im)
{
this->im = im;
}
Complex Complex::operator[](int i)
{
Complex temp;
temp.re = re;
temp.im = im;
return temp;
}
Complex Complex::operator=(const Complex &c)
{
re = c.re;
im = c.im;
return *this;
}
Complex Complex::operator+(const Complex &c)
{
*this = apply(c, [](double x, double y) { return x + y; });
return *this;
}
Complex Complex::operator-(const Complex &c)
{
*this = apply(c, [](double x, double y) { return x - y; });
return *this;
}
Complex Complex::apply(const Complex &c, const std::function<double(double, double)> &f)
{
re = re + c.re;
im = im + c.im;
return *this;
}
Array.cpp
Array::Array(int n)
{
this->n = n;
arr = new Complex[n];
}
Array::Array(const Array &a)
{
this->n = a.n;
arr = new Complex[n];
arr = a.arr;
}
Array::Array(Array &&a)
{
this->n = a.n;
arr = a.arr;
a.arr = nullptr;
}
Array& Array::operator=(const Array &a)
{
this->n = a.n;
arr = new Complex[n];
arr = a.arr;
return *this;
}
Array& Array::operator=(Array &&a)
{
this->n = n;
this->arr = a.arr;
a.arr = nullptr;
return *this;
}
std::ostream& operator<<(std::ostream& out, const Array &a)
{
for (int i = 0; i < a.n; i++)
out << a.arr[i].re << " +i" << a.arr[i].im;
return out;
}
std::istream& operator>>(std::istream& in, Array &a)
{
for (int i = 0; i < a.n; i++)
in >> a.arr[i].re >> a.arr[i].im;
return in;
}
Array Array::operator+(const Array &a)
{
return compute(a, [](Complex x, Complex y) { return x + y; });
}
/*
Array Array::operator-(const Array &a)
{
return compute(a, [](Complex x, Complex y) { return x - y; });
}
*/
Array Array::compute(const Array &a,const std::function<Complex(Complex , Complex)> &f)
{
for (int i = 0; i < n; i++)
arr[i] = f(arr[i], a.arr[i]);
return *this;
}
Array::~Array()
{
delete[] arr;
n = 0;
}
Source.cpp
#include <iostream>
#include "Array.h"
#include "Complex.h"
int main()
{
Array a(2);
std::cin >> a;
Array b;
b = a;
Array c(2);
c = a + b;
std::cout << c;
getchar();
getchar();
}
So this is what i have at the moment, i need to add that this worked just fine before, when in my Complex class i only had setters, getters, these fields and Array class as a friend, which means that i was doing indexing "manually" and operations + and - without overloading of corresponding operators in Complex class.
However, i had an idea that it would be better (and more in the spirit of oop) to overload the operators that i need for Complex class since code would be more readable.
However, even though i get the result i need, every time after execution of program, when i hit enter, error with destructor appears, i tried some debugging and it appears to me that problem appears when object Array b is "destructed", but i could not figure out what actually happens (and is b actually causing the problem in the first place).
NOTE: I've found some questions here related to complex arrays but non of them solved my problem.
Any help appreciated!
I get weird notification that I'm using private members of class - which is entirely valid, but I though that I'm allowed to do so, since I did say that the method I'm using is a friendly one.
Take a look at this:
#include <iostream>
using namespace std;
class complex {
private:
double Re, Im;
public:
complex(): Re(0.0), Im(0.0){}
complex(double Re, double Im): Re(Re), Im(Im){}
double getRe() const { return Re; }
double getIm() const { return Im; }
friend complex operator+(const complex&, const complex&);
friend ostream& operator<<(ostream&, const complex&);
friend istream& operator>>(istream &, const complex &); // FRIENDLY FUNCTION
};
complex operator+(const complex& a, const complex& b) {
double r, i;
r = a.getRe()+ b.getRe();
i = a.getIm() + b.getIm();
return complex(r, i);
}
ostream& operator<<(ostream& out, const complex &a) {
out << "(" << a.getRe() << ", " << a.getIm() << ")" << endl;
return out;
}
istream &operator>>(istream &in, complex &c)
{
cout<<"enter real part:\n";
in>>c.Re; // ** WITHIN THIS CONTEXT ERROR **
cout<<"enter imag part: \n";
in>>c.Im; // ** WITHIN THIS CONTEXT ERROR **
return in;
}
int main(void) {
complex a, b,c;
cin >> a;
cin >> b;
c = a+b;
cout << c;
}
Should I declare some sort of setFunction within the class in order to get the values which are private ?
istream& operator>>(istream &, const complex &);
is not the same as
istream &operator>>(istream &in, complex &c);
Spot the difference left as exercise to the reader.
im new to C++, although i do know the general C syntax. I've been trying to create a class with operator overloading. But i can't get it to work. Well partially got it to work.
Working operator overloading in same source:
//test.cpp
#include <iostream>
class Fraction
{
int gcd(int a, int b) {return b==0 ? a : gcd(b,a%b); }
int n, d;
public:
Fraction(int n, int d = 1) : n(n/gcd(n,d)), d(d/gcd(n,d)) {}
int num() const { return n; }
int den() const { return d; }
Fraction& operator*=(const Fraction& rhs) {
int new_n = n*rhs.n / gcd(n*rhs.n, d*rhs.d);
d = d*rhs.d / gcd(n*rhs.n, d*rhs.d);
n = new_n;
return *this;
}
};
std::ostream& operator<<(std::ostream& out, const Fraction& f){
return out << f.num() << '/' << f.den() ;
}
bool operator==(const Fraction& lhs, const Fraction& rhs) {
return lhs.num() == rhs.num() && lhs.den() == rhs.den();
}
bool operator!=(const Fraction& lhs, const Fraction& rhs) {
return !(lhs == rhs);
}
Fraction operator*(Fraction lhs, const Fraction& rhs)
{
return lhs *= rhs;
}
int main()
{
Fraction f1(3,8), f2(1,2), f3(10,2);
std::cout << f1 << '*' << f2 << '=' << f1*f2 << '\n'
<< f2 << '*' << f3 << '=' << f2*f3 << '\n'
<< 2 << '*' << f1 << '=' << 2 *f1 << '\n';
}
Output:
3/8*1/2=3/16
1/2*5/1=5/2
2*3/8=3/4
Source: http://en.cppreference.com/w/cpp/language/operators
Now my code, trying to apply the code from above
//vectors.h
class Vector2
{
public:
Vector2(void);
~Vector2(void);
int counter;
Vector2& operator+=(const Vector2& vec);
}
//vectors.cpp
#include "vectors.h"
Vector2::Vector2(void)
{
counter = 0;
}
Vector2::~Vector2(void)
{
}
Vector2& operator+=(Vector2& vec)//error: too few parameters
{
int new_n = counter + vec.counter;
counter = new_n;
return *this;//error: this may only be used in a non-static member function.
}
//main.cpp
#include <stdio.h>
#include "vectors.h"
int main(void)
{
Vector2 vector();
while(true)
{
vector += vector;//error: expression must be a modifiable value
printf("Vector counter: %d\n",vector.counter);
}
}
What i'm trying to do:
I'm trying to make my own class, and use operator overloading. But the part i can't get to work is defining the class with a header while keeping operator overloading working.
Thanks for reading my question
The following compiled in ideone: http://ideone.com/ratVVT
Changes are:
Implementation of (overload) method must specify the Class name
Implementation of (overload) method must have the same signature as the declaration (missing const).
Declaring the variable vector in main Vector2 vector(); was interpreted as a function declaration, instead of a Vector2 variable.... use Vector2 vector; or Vector2 vector=Vector2()
The code copied below.
#include <iostream>
//vectors.h
class Vector2
{
public:
Vector2();
~Vector2();
int counter;
Vector2& operator+=(const Vector2& vec);
};
//vectors.cpp
//#include "vectors.h"
Vector2::Vector2()
{
counter = 0;
}
Vector2::~Vector2()
{
}
Vector2& Vector2::operator+=(const Vector2& vec)// <---- CHANGE
{
int new_n = counter + vec.counter;
counter = new_n;
return *this;//error: this may only be used in a non-static member function.
}
//main.cpp
#include <stdio.h>
//#include "vectors.h"
int main()
{
Vector2 vector; // <---- CHANGE
while(true)
{
vector += vector;
printf("Vector counter: %d\n",vector.counter);
}
}
You are missing the class name in your method definition Vector2:: and the signature does not match because of the first parameter missing a const.
Vector2& Vector2::operator+=(const Vector2& vec)
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;
}
//Operators
std::ostream& operator<<(std::ostream& out, const Vector& v) {
out<<"<"<<v.x<<", "<<v.y<<", "<<v.z<<">";
return out;
}
Friend functions aren't member functions, and operator<< needs to not be a member in order to have a left side of ostream. Change it to a free function:
std::ostream& operator<<(std::ostream& out, Vector v) {
^^ no qualification
I would also take the vector by const reference instead of by value.
Your friend function belongs to the namespace vec and must be defined as such.
Change it to:
std::ostream &vec::operator << (std::ostream &out , const Vector &v) { //etc