C++继承基类的子类分文件存放规范及链接问题解决
C++多文件分离实现抽象类与子类的正确方式
核心问题原因
直接将类实现写在同一个cpp或include cpp文件,会导致编译时重复定义类/函数,触发链接错误。正确做法是头文件(.h)放类声明,源文件(.cpp)放成员函数实现,配合头文件保护避免重复包含。
具体文件拆分方案
1. 创建Shape.h(基类声明)
存放纯虚基类的声明,添加头文件保护避免重复包含:
#pragma once #include <cmath> class Shape { public: virtual void Area() = 0; // 纯虚函数,仅声明无需实现 virtual ~Shape() = default; // 必须添加虚析构,避免子类内存泄漏 };
2. 创建Square.h(Square类声明)
包含基类头文件,声明Square类的结构:
#pragma once #include "Shape.h" class Square : public Shape { private: int height, width; public: Square(); // 构造函数声明 void Area() override; // 重写的Area函数声明 };
3. 创建Square.cpp(Square类实现)
实现Square类的成员函数:
#include "Square.h" #include <cstdio> Square::Square() { height = 5; width = 5; } void Square::Area() { printf("%d\n", height * width); }
4. 创建Circle.h(Circle类声明)
包含基类头文件,声明Circle类的结构:
#pragma once #include "Shape.h" class Circle : public Shape { private: int radius; public: Circle(); void Area() override; };
5. 创建Circle.cpp(Circle类实现)
实现Circle类的成员函数:
#include "Circle.h" #include <cstdio> #include <cmath> Circle::Circle() { radius = 10; } void Circle::Area() { double x = pow(radius, 2); printf("%lf\n", 3.14 * x); }
6. 修改ShapeTest.cpp(测试文件)
仅包含对应头文件,禁止include cpp文件:
#include "Square.h" #include "Circle.h" int main() { Square square{}; Circle circ{}; square.Area(); circ.Area(); // 若使用多态特性,可按如下写法: // Shape* s1 = new Square(); // Shape* s2 = new Circle(); // s1->Area(); // s2->Area(); // delete s1; // delete s2; return 0; }
编译与链接
以g++为例,需将所有源文件一起编译链接:
g++ ShapeTest.cpp Square.cpp Circle.cpp -o ShapeTest
运行生成的可执行文件:
./ShapeTest
关键注意点
- 头文件必须添加保护(
#pragma once或#ifndef SHAPE_H #define SHAPE_H ... #endif),防止重复包含导致的重复声明错误。 - 纯虚基类必须添加虚析构函数,否则通过基类指针销毁子类对象时,子类析构函数不会被调用,引发内存泄漏。
- 禁止在源文件中include其他cpp文件,必须include对应的头文件,否则会导致代码被多次编译,出现
multiple definition链接错误。
内容的提问来源于stack exchange,提问作者kopo222
相关产品推荐
相关产品推荐

