C++中class Point重定义及默认构造函数未实现问题求助
问题背景
完成面向对象编程作业时,编写了Point.h、Triangle.h头文件及Point.cpp、Triangle.cpp实现文件,代码混用英文与西班牙语。编译时先后遇到两个错误:
错误1:class Point重定义
编译命令:
PS C:\Users\ikerc\OneDrive\Escritorio\C++\TC1033\Clases\Act6> g++ main.cpp Point.cpp Triangle.cpp
错误信息:
In file included from Triangle.h:3,
from main.cpp:3:
Point.h:5:7: error: redefinition of 'class Point'
5 | class Point{
| ^~~~~
In file included from main.cpp:2:
Point.h:5:7: note: previous definition of 'class Point'
5 | class Point{
错误2:添加#pragma once后出现默认构造函数未定义
错误信息:
C:\Users\ikerc\AppData\Local\Temp\cchgOY8H.o:Triangle.cpp:(.text+0x22): undefined reference to `Point::Point()'
错误原因及解决方案
1. 解决class Point重定义错误
原因:头文件被多次包含(main.cpp直接包含Point.h,同时Triangle.h也包含Point.h,导致Point类被重复定义)。
解决方案:在所有头文件中添加头文件保护,两种常用方式:
- 方式一:使用
#pragma once(编译器支持,写法简单) - 方式二:使用标准
#ifndef头文件保护(跨平台兼容性更好)
推荐在Point.h和Triangle.h顶部添加#pragma once:
修改后的Point.h开头:
#pragma once #include<iostream> #include<cmath>
修改后的Triangle.h开头:
#pragma once #include<iostream> #include"Point.h"
2. 解决Point默认构造函数未定义错误
原因:Point.h中声明了默认构造函数Point();,但Point.cpp中没有实现它。Triangle默认构造函数创建vertex1、vertex2、vertex3时,会调用Point的默认构造函数,找不到实现就会报错。
解决方案:在Point.cpp中添加默认构造函数的实现,比如将成员变量初始化为0:
在Point.cpp中添加:
Point::Point() : x(0), y(0), distancia(0) {}
修正后的完整代码
修正后的Point.h
#pragma once #include<iostream> #include<cmath> class Point{ public: Point(double, double); Point(); double getX(); double getY(); double getDistance(); void setX(double); void setY(double); double distance(Point); protected: double x; double y; double distancia; };
修正后的Point.cpp
#include<iostream> #include"Point.h" Point::Point(double _x, double _y){ x = _x; y = _y; } // 添加默认构造函数实现 Point::Point() : x(0), y(0), distancia(0) {} double Point::getX(){ return x; } double Point::getY(){ return y; } double Point::getDistance(){ return distancia; } void Point::setX(double _x){ x = _x; } void Point::setY(double _y){ y = _y; } double Point::distance(Point Punto){ distancia = sqrt(pow(Punto.getX() - x, 2) + pow(Punto.getY() - y, 2)); //Distancia entre puntos formula return distancia; }
修正后的Triangle.h
#pragma once #include<iostream> #include"Point.h" class Triangle: public Point{ public: Triangle(Point, Point, Point); Triangle(); double perimeter(); double area(); private: Point vertex1; Point vertex2; Point vertex3; double sideA; double sideB; double sideC; double areaT; double perimeterT; };
修正后的Triangle.cpp(补充周长调用逻辑,避免area计算异常)
#include<iostream> #include"Triangle.h" #include<cmath> Triangle::Triangle(Point _vertex1, Point _vertex2, Point _vertex3){ vertex1 = _vertex1; vertex2 = _vertex2; vertex3 = _vertex3; } Triangle::Triangle(){ vertex1.setX(0); vertex1.setY(0); vertex2.setX(50); vertex2.setY(30); vertex3.setX(25); vertex3.setY(10); } double Triangle::perimeter(){ sideA = vertex1.distance(vertex2); sideB = vertex2.distance(vertex3); sideC = vertex3.distance(vertex1); perimeterT = sideA + sideB + sideC; return perimeterT; } double Triangle::area(){ // 先调用perimeter确保perimeterT已初始化 perimeter(); double s = perimeterT / 2; areaT = sqrt(s * (s - sideA) * (s - sideB) * (s - sideC)); // Formula Heron return areaT; }
修正后的main.cpp
#include<iostream> #include"Point.h" #include"Triangle.h" int main(){ Point Punto1(7, 5); Point Punto2(4, 1); Triangle Tr; Punto1.distance(Punto2); std::cout<<"\n\nLa distancia entre los puntos es: "<<Punto1.getDistance(); std::cout<<"\nEl area del triangulo es: "<<Tr.area(); return 0; }
额外优化提示
Triangle类无需继承Point:三角形不需要拥有Point的属性,只需要包含三个Point对象即可,可去掉继承关系,避免不必要的设计冗余。- 只读成员函数可加
const修饰:比如double getX() const;,明确函数不修改对象状态,提升代码安全性。 - 构造函数优先用初始化列表:比如
Point::Point(double _x, double _y) : x(_x), y(_y) {},比赋值操作效率更高。
内容的提问来源于stack exchange,提问作者Iker Casillas

