C++错误:未定义对...的引用和多个定义

C++ error: undefined reference to ... & multiple definition of

本文关键字:定义 引用 错误 未定义 C++      更新时间:2023-10-16

我是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 filen";
    }
}
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 << "mainn";
    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

#include "geo.cpp"

,#include "geo.h"

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

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

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

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

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

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

c++改进技巧:

  • 不要在头文件中使用"using…"
  • 把include守卫放在头文件的最上面。