C ++错误:未定义引用...&多重定义

时间:2014-03-14 08:17:28

标签: c++ netbeans

我是C ++的新手。我正在使用netbeans IDE。我创建了类 Point (Point.h和Point.cpp)以及另一个c ++文件 geo.cpp 其中我已经把方法用在了之后。我还创建了一个头文件,其中我 geo.h 我已经在 geo.cpp中实现了方法的声明 。我的代码如下:

Point.h

#include <math.h>
#include <iostream>
using namespace std;

#ifndef POINT_H
#define POINT_H

class Point {
protected:
    double x;
    double y;
    double z;
    // color RGB
    double r;
    double g;
    double b;
public:
    // Constructors
    Point();
    //  Point(const Point& orig);
    Point(ostream &strm);
    Point(double x, double y, double z);
    Point(double *tab);
    Point(const Point& orig);
    virtual ~Point();

    //getters

    double getX() const {
        return this->x;
    }

    double getY() const {
        return this->y;
    }

    double getZ() const {
        return this->z;
    }

    double getR() const {
        return this->r;
    }

    double getG() const {
        return this->g;
    }

    double getB() const {
        return this->b;
    }

    //setters

    void setX(double x) {
        this->x = x;
    }

    void setY(double y) {
        this->y = y;
    }

    void setZ(double z) {
        this->z = z;
    }

    void setR(double r) {
        this->r = r;
    }

    void setG(double g) {
        this->g = g;
    }

    void setB(double b) {
        this->b = b;
    }

    void setColor(double r, double g, double b) {
        this->r = r;
        this->g = g;
        this->b = b;
    }

    /**
     * Print the point
     * @param strm
     */
    void print(ostream &strm);

    //Other methods

    double dist2D(Point &other);

    double dist3D(Point &other);

    Point swap(Point p);

    Point operator-(const Point &other) const;

};

#endif  /* POINT_H */

Point.cpp

#include <iostream>
#include <math.h>
#include <ostream>
using namespace std;

#include "Point.h"

Point::Point(const Point& orig) {
}

Point::Point(ostream &strm) {
    strm << "Type the abscissa: ", cin >> this->x;
    strm << "Type the ordinate: ", cin >> this->y;
    strm << "Type the applicate: ", cin >> this->z;
}

Point::Point(double x, double y, double z) : x(x), y(y), z(z) {
    // The default point color is blue
    this->r = 0;
    this->g = 0;
    this->b = 255;
}

Point::Point(double *tab) : x(tab[0]), y(tab[1]), z(tab[2]) {
    // The default point color is blue
    r = 0;
    g = 0;
    b = 255;
}

Point::~Point() {

}

//Other methods

double Point::dist2D(Point &other) {
    double xd = x - other.x;
    double yd = y - other.y;
    return sqrt(xd * xd + yd * yd);
}

double Point::dist3D(Point &other) {
    double xd = x - other.x;
    double yd = y - other.y;
    double zd = z - other.z;
    return sqrt(xd * xd + yd * yd + zd * zd);
}

Point Point::swap(Point p) {
    Point aux(x, y, z);
    x = p.x;
    y = p.y;
    z = p.z;
    return aux;
}

Point Point::operator-(const Point &other) const {
    return Point(other.getX() - this->x, other.getY() - this->y, other.getZ() - this->z);
}

void Point::print(ostream &strm) {
    strm << "Point(" << this->x << "," << y << "," << z << ")\n";
}

geo.h

#include <vector>
#include <stack>

using namespace std;
#include "Point.h"

#ifndef GEO_H
#define GEO_H

double myRand(double min, double max);

void PCEngine(char *theFileName, int pointsNBR);

void getFarthestPoints(vector<Point> v, Point &p1, Point &p2);

vector<Point> getCloudPoint(char *fileName);

void loadPointCloud(char *fileName, Point p[]);

int getLineNbr(char *fileName);

double myRand(double min, double max);

Point nextToTop(stack<Point> &S);

int orientation(Point p, Point q, Point r);

int compare(const void *vp1, const void *vp2);

vector<Point> convexHull(Point Points[], int n);

#endif  /* GEO_H */

geo.cpp

#include <cstdlib>
#include <string>
#include <vector>
#include <stack>
#include <fstream>
#include <sstream>

using namespace std;

#include "geo.h"
#include "Point.h"

Point p0 = NULL;

double myRand(double min, double max) {
    return (double) (min + ((float) rand() / RAND_MAX * (max - min + 1.0)));
}

int getLineNbr(char *fileName) {
    string line;
    int nbr = 0;
    ifstream file(fileName);
    if (file.is_open()) {
        while (getline(file, line)) {
            ++nbr;
        }
        file.close();
    } else {
        cout << "Unable to open " << fileName << '\n';
        exit(0);
    }
    return 0;
}

void loadPointCloud(char *fileName, Point Points[]) {
    string line;
    string token;
    double tab[3];
    ifstream file(fileName);
    if (file.is_open()) {
        int lineNbr = -1;
        while (getline(file, line)) {
            ++lineNbr;
            int cpt = 0;
            stringstream stream(line);
            while (getline(stream, token, ',')) {
                tab[cpt] = ::atof(token.c_str());
                ++cpt;
            }
            Point p(tab[0], tab[1], tab[2]);
            p.setColor(myRand(0, 255), myRand(0, 255), myRand(0, 255));
            Points[lineNbr] = p;
        }
        file.close();
    } else {
        cout << "Unable to open " << fileName << '\n';
        exit(0);
    }
}

vector<Point> getCloudPoint(char *fileName) {
    string line;
    string token;
    vector<Point> v;
    double tab[3];
//    double x;
//    double y;
//    double z;
    ifstream file(fileName);
    if (file.is_open()) {
        while (getline(file, line)) {
            int cpt = 0;
            stringstream stream(line);
            while (getline(stream, token, ',')) {
                tab[cpt] = ::atof(token.c_str());
                cpt++;
            }
            Point p(tab[0], tab[1], tab[2]);
            p.setColor(myRand(0, 255), myRand(0, 255), myRand(0, 255));
            v.push_back(p);
        }
        file.close();
    } else {
        cout << "Unable to open " << fileName << '\n';
        exit(0);
    }

    return v;
}

/**
 * This is an Engine to generate the points
 *  and to save their in the "file".csv
 * 
 * @param theFileName
 * @param pointsNBR points number
 */
void PCEngine(char *theFileName, int pointsNBR) {
        cout << "PCEngine : Ok!\n";
    ofstream file(theFileName);
    if (file.is_open()) {
        cout << "Ok!\n";
        for (int i = 0; i < pointsNBR; i++) {
            file << myRand(-1, 1) << "," << myRand(-1, 1) << "," << myRand(-1, 1) << "\n";
        }
        file.close();
    } else {
        cout << "Unable to open file\n";
    }
}

void getFarthestPoints(vector<Point> v, Point &p1, Point &p2) {
    if (v.size() < 2) {
        cout << "The number of points is very small.\n";
        exit(0);
    } else {
        int indexP1 = -1;
        int indexP2 = -1;
        double maxDist = 0;
        double dist = 0;
        for (int i = 0; i < v.size() - 1; ++i) {
            for (int j = i + 1; j < v.size(); ++j) {
                dist = v[i].dist3D(v[j]);
                if (maxDist < dist) {
                    maxDist = dist;
                    indexP1 = i;
                    indexP2 = j;
                }
            }
        }
        p1 = v[indexP1];
        p1.print(cout);
        p2 = v[indexP2];
        p2.print(cout);
    }
}

/** An utility function to find next to top in a stack */
Point nextToTop(stack<Point> &S) {
    Point p = S.top();
    S.pop();
    Point res = S.top();
    S.push(p);
    return res;
}

int orientation(Point p, Point q, Point r) {
    int val = (q.getY() - p.getY()) * (r.getX() - q.getX()) -
            (q.getX() - p.getX()) * (r.getY() - q.getY());

    if (val == 0) return 0;
    // colinear
    return (val > 0) ? 1 : 2; // clock or counterclock wise
}

// A function used by library function qsort() to sort an array of
// Points with respect to the first Point

int compare(const void *vp1, const void *vp2) {
    Point *p1 = (Point *) vp1;
    Point *p2 = (Point *) vp2;

    // Find orientation
    int o = orientation(p0, *p1, *p2);
    if (o == 0) {
        //the distance square between p0 and p1
        double distSquare1 = p0.dist2D(*p1) * p0.dist2D(*p1);
        //the distance square between p0 and p2
        double distSquare2 = p0.dist2D(*p2) * p0.dist2D(*p2);
        return (distSquare2 >= distSquare1) ? -1 : 1;
    }

    return (o == 2) ? -1 : 1;
}

vector<Point> convexHull(Point Points[], int n) {
    vector<Point> v;
    // Find the bottommost Point
    int ymin = Points[0].getY();
    int min = 0;
    for (int i = 1; i < n; i++) {
        int y = Points[i].getY();

        // Pick the bottom-most or chose the left most Point in case of tie
        if ((y < ymin) || (ymin == y && Points[i].getX() < Points[min].getX()))
            ymin = Points[i].getY(), min = i;

    }
    // Place the bottom-most Point at first position
    Points[min] = Points[0].swap(Points[min]);

    // Sort n-1 Points with respect to the first Point. A Point p1 comes
    // before p2 in sorted ouput if p2 has larger polar angle (in 
    // counterclockwise direction) than p1
    p0 = Points[0];
    qsort(&Points[1], n - 1, sizeof (Point), compare);

    // Create an empty stack and push first three Points to it.
    stack<Point> S;
    S.push(Points[0]);
    S.push(Points[1]);
    S.push(Points[2]);

    // Process remaining n-3 Points
    for (int i = 3; i < n; i++) {
        // Keep removing top while the angle formed by Points next-to-top, 
        // top, and Points[i] makes a non-left turn
        while (orientation(nextToTop(S), S.top(), Points[i]) != 2)
            S.pop();
        S.push(Points[i]);

    }

    // Now stack has the output Points, print contents of stack
    while (!S.empty()) {
        Point p = S.top();
        cout << "(" << p.getX() << ", " << p.getY() << ")" << endl;
        v.push_back(Point(p.getX(), p.getY(), 0));
        S.pop();
    }
    return v;
}

的main.cpp

#include <cstdlib>
#include <iostream>
#include <string>

using namespace std;

#include "Point.h"
#include "geo.cpp"

int main(int argc, char** argv) {
    cout << "main\n";
    char *theFileName = "file.csv";
    PCEngine(theFileName, 100);
    return 0;
}

当我运行项目时,我发现了以下错误:

main.cpp: In function ‘int main(int, char**)’:
main.cpp:20:29: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
mkdir -p dist/Debug/GNU-Linux-x86
g++     -o dist/Debug/GNU-Linux-x86/dgilog build/Debug/GNU-Linux-x86/Plan.o build/Debug/GNU-Linux-x86/Point.o build/Debug/GNU-Linux-x86/Straight.o build/Debug/GNU-Linux-x86/Vect.o build/Debug/GNU-Linux-x86/geo.o build/Debug/GNU-Linux-x86/main.o 
/usr/bin/ld: error: build/Debug/GNU-Linux-x86/main.o: multiple definition of 'p0'
/usr/bin/ld: build/Debug/GNU-Linux-x86/geo.o: previous definition here
/usr/bin/ld: error: build/Debug/GNU-Linux-x86/main.o: multiple definition of 'myRand(double, double)'
/usr/bin/ld: build/Debug/GNU-Linux-x86/geo.o: previous definition here
/usr/bin/ld: error: build/Debug/GNU-Linux-x86/main.o: multiple definition of 'getLineNbr(char*)'
/usr/bin/ld: build/Debug/GNU-Linux-x86/geo.o: previous definition here
/usr/bin/ld: error: build/Debug/GNU-Linux-x86/main.o: multiple definition of 'loadPointCloud(char*, Point*)'
/usr/bin/ld: build/Debug/GNU-Linux-x86/geo.o: previous definition here
/usr/bin/ld: error: build/Debug/GNU-Linux-x86/main.o: multiple definition of 'getCloudPoint(char*)'
/usr/bin/ld: build/Debug/GNU-Linux-x86/geo.o: previous definition here
/usr/bin/ld: error: build/Debug/GNU-Linux-x86/main.o: multiple definition of 'PCEngine(char*, int)'
/usr/bin/ld: build/Debug/GNU-Linux-x86/geo.o: previous definition here
/usr/bin/ld: error: build/Debug/GNU-Linux-x86/main.o: multiple definition of 'getFarthestPoints(std::vector<Point, std::allocator<Point> >, Point&, Point&)'
/usr/bin/ld: build/Debug/GNU-Linux-x86/geo.o: previous definition here
/usr/bin/ld: error: build/Debug/GNU-Linux-x86/main.o: multiple definition of 'nextToTop(std::stack<Point, std::deque<Point, std::allocator<Point> > >&)'
/usr/bin/ld: build/Debug/GNU-Linux-x86/geo.o: previous definition here
/usr/bin/ld: error: build/Debug/GNU-Linux-x86/main.o: multiple definition of 'orientation(Point, Point, Point)'
/usr/bin/ld: build/Debug/GNU-Linux-x86/geo.o: previous definition here
/usr/bin/ld: error: build/Debug/GNU-Linux-x86/main.o: multiple definition of 'compare(void const*, void const*)'
/usr/bin/ld: build/Debug/GNU-Linux-x86/geo.o: previous definition here
/usr/bin/ld: error: build/Debug/GNU-Linux-x86/main.o: multiple definition of 'convexHull(Point*, int)'
/usr/bin/ld: build/Debug/GNU-Linux-x86/geo.o: previous definition here
collect2: ld returned 1 exit status
make[2]: *** [dist/Debug/GNU-Linux-x86/dgilog] Error 1
make[2]: Leaving directory `/home/abouabdillehmsk/NetBeansProjects/DGILOG'
make[1]: *** [.build-conf] Error 2
make[1]: Leaving directory `/home/abouabdillehmsk/NetBeansProjects/DGILOG'
make: *** [.build-impl] Error 2

我已经替换了包含

#include "geo.cpp"

通过     #include "geo.h"

编译器没有给我任何错误,但是当我检查输出文件file.csv时,它仍然是空的。

在创建文件之前知道一切正常:geo.h和geo.cpp

提前致谢。

2 个答案:

答案 0 :(得分:3)

  1. 在main.cpp中,您包含了.cpp文件而不是头文件。 从不包含实施文件。
  2. 切勿在头文件中使用using namespace。如果要使用命名空间,请首选namespace { }
  3. 必须在任何包含之前完成多重包含保护。
  4. #ifndef POINT_H
    #define POINT_H
    
    #include <math.h>
    #include <iostream>
    
    //code 
    
    #endif
    

答案 1 :(得分:1)

请删除您已解决的中间错误。

您需要在编译命令中包含geo.cpp:

g++ main.cpp geo.cpp -o main.out

c ++改进提示:

  • 切勿在标题文件中使用“using ...”。
  • 在头文件的最顶部放置包含警卫。