使用 #include 和包含防护在单独文件中进行 C++ 继承

2024-01-18

我是 Stack Overflow 的新手,正在自学 C++,但我仍然是一个初学者。在完成了我正在使用的书中的大部分内容(可能被认为是过时的和/或不是一本好书)后,我决定通过自己尝试来重新强化一些概念,仅在需要时参考这本书,但我似乎被卡住了。我试图解决的概念是继承、多态性、抽象数据类型 (ADT) 以及将类的代码分为头文件 (.h) 和 C++ 文件 (.cpp)。提前对文字墙表示抱歉,我只是想清楚具体地说明我需要的地方。

因此,我的目标是创建简单的形状类,在适用的情况下相互继承。我有四个类:myPoly、myRectangle、myTriangle 和 mySquare。 myPoly,如果我正确理解这个概念,应该是一个 ADT,因为其中一个方法是纯虚函数(区域方法),因为创建 myPoly 对象不是我希望类的用户执行的操作。 myRectangle 和 myTriangle 均派生自 myPoly,而 mySquare 又派生自 myRectangle。我还包括了我计划测试我的课程的测试程序。我正在使用 Code::Blocks 10.05,并在构建 test.cpp 程序时不断收到以下错误:

undefined reference to 'myPoly::myPoly()'

对于 myPoly 类的方法,我收到 42 个类似的错误。当我尝试为 myRectangle 和 myTriangle 构建 .cpp 文件时也会发生这种情况。通过我尝试对这个小项目遇到的问题进行的研究,我觉得我的包含防护或我的 #include 语句出了问题,并且某些内容没有正确包含或包含太多次。起初,我将 myPoly 的 .cpp 文件提供给 myRectangle 和 myTriangle,但在几个地方读到,包含 myPoly 的 .h 文件会更有效,并且会自动包含其 .cpp。如果有人能对此提供一些见解,我们将不胜感激。我还记得在包含语句中使用引号与使用尖括号有何不同。以下是我为我的小项目制作的所有九个文件。大多数评论对我来说都是小注释或提醒。

myPoly.h

//Practice with inheritance, polymorphism, and Abstract Data Types
//header file for Polygon class

#ifndef MYPOLY_H
#define MYPOLY_H

class myPoly
{
    public:
        //constructor
        //const reference pass because the values w and h don't change and reference avoid the time it takes to copy large
        //  objects by value (if there were any)
        myPoly();
        myPoly(const float & w, const float & h);

        //destructor
        virtual ~myPoly();

        //accessors
        float getWidth();
        float getHeight();
        void setWidth(const float & w);
        void setHeight(const float & h);

        virtual float area() = 0;

    private:
        float width, height;
};

#endif

myPoly.cpp

//Practice with inheritance, polymorphism, and Abstract Data Types
//implementation file for myPoly class

#include "myPoly.h"

//constructor
myPoly::myPoly()
{
    setWidth(10);
    setHeight(10);
}

myPoly::myPoly(const float & w, const float & h)
{
    setWidth(w);
    setHeight(h);
}

//destructor
myPoly::~myPoly() {}

//accessors
float myPoly::getWidth() {return width;}
float myPoly::getHeight() {return height;}

void myPoly::setHeight(const float & w) {width = w;}
void myPoly::setWidth(const float & h) {height = h;}

//pure virtual functions have no implementation
//area() is handled in the header file

myRectangle.h

//Practice with inheritance, polymorphism, and Abstract Data Types
//declaration file for myRectangle class

#ifndef MYRECTANGLE_H
#define MYRECTANGLE_H

#include "myPoly.h"

class myRectangle : public myPoly
{
    public:
        //constructor
        myRectangle();
        myRectangle(const float & w, const float & h);

        //destructor
        ~myRectangle();

        //this doesn't need to be virtual since the derived class doesn't override this method
        float area();
};

#endif

myRectangle.cpp

//Practice with inheritance, polymorphism, and Abstract Data Types
//implementaion file for the myRectangle class

//get a vauge compiler/linker error if you have virtual methods that aren't implemented (even if it ends up being just
//  a 'stub' method, aka empty, like the destructor)

#include "myRectangle.h"

myRectangle::myRectangle()
{
    setWidth(10);
    setHeight(10);
}

myRectangle::myRectangle(const float & w, const float & h)
{
    setWidth(w);
    setHeight(h);
}

myRectangle::~myRectangle()
{
}

float myRectangle::area()
{
    return getWidth() * getHeight();
}

myTriangle.h

//Practice with inheritance, polymorphism, and Abstract Data Types
//declaration file for myTriangle class

#ifndef MYTRIANGLE_H
#define MYTRIANGLE_H

#include "myPoly.h"

//imagine the triangle is a right triangle with a width and a height
//  |\
//  | \
//  |  \
//  |___\

class myTriangle : public myPoly
{
    public:
        //constructors
        myTriangle();
        myTriangle(const float & w, const float & h);

        //destructor
        ~myTriangle();

        //since nothing derives from this class it doesn't need to be virtual and in turn neither does the destructor
        float area();
};

#endif

myTriangle.cpp

//Practice with inheritance, polymorphism, and Abstract Data Types
//implementation file for myTriangle class

#include "myTriangle.h"

myTriangle::myTriangle()
{
    setWidth(10);
    setHeight(10);
}

myTriangle::myTriangle(const float & w, const float & h)
{
    setWidth(w);
    setHeight(h);
}

myTriangle::~myTriangle()
{
}

float myTriangle::area()
{
    return getWidth() * getHeight() / 2;
}

mySquare.h

//Practice with inheritance, polymorphism, and Abstract Data Types
//declaration file for mySquare class

#ifndef MYSQUARE_H
#define MYSQUARE_H

#include "myRectangle.cpp"

class mySquare : public myRectangle
{
    public:
        //constructors
        mySquare();
        //explicity call the myRectangle constructor within this implementation to pass w as width and height
        mySquare(const float w);

        //destructor
        ~mySquare();
};

#endif

mySquare.cpp

//Practice with inheritance, polymorphism, and Abstract Data Types
//implementation file for mySquare class

#include "mySquare.h"

mySquare::mySquare()
{
    setWidth(10);
    setHeight(10);
}

mySquare::mySquare(const float w)
{
    myRectangle::myRectangle(w, w);
}

mySquare::~mySquare()
{
}

test.cpp

//Practice with inheritance, polymorphism, and Abstract Data Types
//main class that uses my shape classes and experiments with inheritance, polymorphism, and ADTs

#include "myRectangle.cpp"
//#include "mySquare.cpp"
#include "myTriangle.cpp"

#include <iostream>

int main()
{
    myPoly * shape = new myRectangle(20,20);

    return 0;
}

我很好奇为什么我会收到这些错误,或者为什么我所做的事情可能不被认为是好的/最佳实践,而不是仅仅接收一行代码来让我的错误消失。


你的包含守卫看起来不错。如果不是,您很可能会收到编译器错误,包括文件和行号信息。您发布的错误看起来更像是链接器错误。

但是,您的代码存在一个“问题”。作为一般规则,您应该只#include.h 文件而不是 .cpp 文件。

现在来谈谈解决方案:我自己对 Code::Blocks 并不熟悉。不过,我希望我能提供一些一般信息,为您指明正确的方向。我过去使用的一些编译器默认允许我编译单个 C++ 文件并运行该程序。要编译具有多个文件的程序,我必须创建一个项目。 (大多数现代编译器强制您从一开始就创建一个项目。)考虑到这一点,我建议您在 Code::Blocks 中查看如何为您的程序创建项目。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 #include 和包含防护在单独文件中进行 C++ 继承 的相关文章

随机推荐

  • Angucomplete Alt:在获得服务器响应之前获取“未找到结果”

    我试图在 3 个字符后发起请求 但一旦输入 3 个字符 我就会收到 未找到记录 错误 之后我可以发现服务调用已完成 但自动完成中未显示任何内容 仅自动完成下的错误消息 下拉菜单 我在这里缺少什么 HTML 代码
  • 如何判断当前框架是否是父框架?

    我正在一个框架环境中工作 并试图判断执行某些 javascript 代码的框架是否是顶部框架 包含其余部分的框架 到目前为止我一直在尝试检查它 window parent null 但它总是返回 false 就像这个简单的例子一样 h1 O
  • setInterval 中的 JavaScript 函数

    我有以下代码 var foo 5 var los function alert foo setInterval los 1000 哪个工作正常 如果我将其更改为 var los function alert foo setInterval
  • 导出到 Excel JSF 和 PrimeFaces

    使用 JDK 1 6 JSF 2 1 PrimeFaces 2 2 1 POI 3 2 和 Apache Tomcat 7 我正在尝试设置一个 servlet 以允许根据用户选择下载 Excel 文件 Excel 文档是在运行时创建的 没有
  • 绕过pip卸载的确认提示

    我正在尝试卸载超级用户环境中的所有 django 软件包 以确保所有 webapp 依赖项都安装到我的 virtualenv 中 sudo su sudo pip freeze grep E django xargs pip q unins
  • 在 Unix 上的 Perforce 中,如何添加符号链接目录?

    我在 Unix 中创建了一个符号链接目录 我想将其添加到 perforce 这个问题与 Unix 上的符号链接有关 Windows 符号链接的行为与 Unix 非常不同 http en wikipedia org wiki Symbolic
  • 有没有办法改变弹性标题的字体大小?

    有没有办法改变弹性标题的字体大小 我使用了 set caption 命令 效果很好 但我不喜欢从 Markdown 编织到 HTML 时的字体大小 None
  • 如何在 PyQt 中隐藏布局?

    我的代码包含一个垂直框布局 它是左侧垂直框布局和右侧垂直框布局的组合 我想知道是否有一种方法可以在发出某个信号时隐藏左侧布局及其所有小部件 您可以作弊并使用框架而不是布局 它的工作方式完全相同 除了您必须在框架上设置布局才能使其正常工作 然
  • 在 bash 中,如何强制刷新打印到终端的不完整行

    我正在编写一个脚本 它执行如下操作 echo n Doing stuff wait for it do stuff 0 echo SUCCESS echo FAILURE 请原谅糟糕的 bash 技能 无论如何 问题是该行的第一部分直到do
  • python 编译所需的 vcvarsall.bat 从 Visual Studio 2015 (v 14) 中缺失

    我正在尝试在 Windows 10 下的 python 3 5 中安装 numpy 并安装了 Visual Studio 2015 Ultimate 简短版本 文件vcvarsall batvs14 文件夹中丢失C Program File
  • 将 DataMember 添加到 DataContract 的不同命名空间

    随着XmlSerializer我可以让我的成员位于与父类型不同的命名空间中 我可以做同样的事情吗DataContractSerializer 我想要以下 XML
  • 这是托管使用 Nodejs、Angularjs、Mongodb 开发的平均应用程序的最佳方式(方法)

    我是这个 Web 开发的新手 我需要知道托管我开发的应用程序的不同方式 这是一个带有链接的粗略清单 对于 MEAN Stack 您可以从Node js安装 https nodejs org en 它为其余部分提供命令框架 当您从头开始时 我
  • numpy 为何这么快?

    我试图理解如何numpy可以这么快 基于我与优化的 C C 代码的令人震惊的比较 它距离再现 numpy 的速度还很远 考虑以下示例 给定一个二维数组shape N N and dtype float32 它表示 N 个维度的 N 个向量的
  • MySQL 性能:多表与单表和分区上的索引

    我想知道什么在性能上更高效 更快 在一张大表上有一个索引 还是在多个没有索引的小表上有索引 由于这是一个非常抽象的问题 让我把它变得更实际 我有一张表 其中包含有关用户的统计信息 20 000 个用户 总共约 3000 万行 该表大约有 1
  • Hazelcast 专用节点

    在专用服务器上运行 Hazelcast 节点的最简单方法是什么 我们有一个使用 Hazelcast 分布式地图的 Web 应用程序 目前 Hazelcast 节点配置为在 Servlet 容器节点中运行 随着规模的扩大 我们希望添加专用硬件
  • AngularJS $timeout 函数未在我的 Jasmine 规范中执行

    我正在尝试使用 Karma 与 Jasmine 测试我的 AngularJS 控制器 但一个 timeout这在现实生活中运行良好 但却使我的测试崩溃 控制器 var Ctrl function scope timeout scope do
  • 在网站上查找一个单词并获取其页面链接

    我想抓取一些网站 看看那里是否存在 katalog 一词 如果是 我想检索该单词所在的所有选项卡 子页面的链接 可以这样做吗 我尝试按照本教程进行操作 但最终得到的 wordlist csv 是空的 即使网站上确实存在单词目录 https
  • 如何将图像裁剪为圆形且圆形内有网格

    In my Social media app i want image Cropping Functionality that Crop image in Circle shape plus have Grid inside Circle
  • 如何在 Rails 中以简单形式添加开关切换按钮

    我正在使用 Rails 4 和 Simple Form with Bootstrap 我希望我的复选框不会那样 但类似的东西 我有CSS
  • 使用 #include 和包含防护在单独文件中进行 C++ 继承

    我是 Stack Overflow 的新手 正在自学 C 但我仍然是一个初学者 在完成了我正在使用的书中的大部分内容 可能被认为是过时的和 或不是一本好书 后 我决定通过自己尝试来重新强化一些概念 仅在需要时参考这本书 但我似乎被卡住了 我