繁体   English   中英

在C ++中实现虚函数和继承

[英]implementing virtual function and inheritance in C++

所以我有这些头文件:

Shape.h:

class Shape
{
public:
    Shape();
    virtual ~Shape();
    virtual double getArea();
    virtual void printDraw();
    bool isLegal(Shape shape);
};

Trig.h:

class Trig : public Shape
{
public:
    Trig(Point pointA, Point pointB, Point pointC);
    virtual ~Trig();
    virtual double getArea();//override
    virtual void printDraw();//override
    bool isLegal(Trig trig);//override
};

但是当我尝试实现Trig.cpp时,出现错误。 我试过了 :

Trig::Trig(Point pointA, Point pointB, Point pointC) {..}

我已经浏览了互联网,但似乎无法正确进行继承。 [我的代码必须具有仅包含声明的头文件!...分配要求!]

我是在C ++中同时使用继承和虚函数的新手[我在Java中使用继承]

关于虚拟功能,它们的实现与正常功能有什么区别吗? [我了解行为上的差异]。

评论中,您解释说

“我收到错误:对`Shape :: Shape()'的未定义引用”

这意味着您忘记了提供该构造函数的实现。

现在,解决技术问题后,看看设计。

前两个方法有两个弊端:(1)尽管它们永远都不应突变对象,但它们并未声明为const ,因此无法在const对象上调用它们;(2) get前缀降低了可读性,其类型更多,并且没有一般优势。 我发现get前缀在某些罕见的情况下可用作消歧设备,但是初学者看到的所有用法都不适当地复制了Java约定,这在Java中是有意义的,但在C ++中是没有意义的。 所以,而不是…

virtual double getArea();
virtual void printDraw();

virtual double area() const;
virtual void print() const;

然后,该方法...

bool isLegal(Shape shape);

在很多方面都是错的...哎呀! 但是,让我们从纯粹的技术开始。

从纯粹的技术角度来看,按值传递参数是不必要的,这会导致每次调用都进行复制操作。 而是通过引用传递对象。 并引用const ,以支持const对象和rvalue对象作为参数:

bool isLegal(Shape const& shape);

接下来,命名: isLegal是一个不好的名字,因为大多数任何C ++对象都是合法的。 为了成为非法,它必须是色情的并且居住在一个非西方国家中。 而且我一辈子都无法想像使物体色情或使其驻留在某些特定地理区域的任何方法。

所以,

bool isValid(Shape const& shape);

接下来,是低级设计,没有充分的理由将非virtual方法用作普通成员函数,因为这要求您在对象上调用它。 但是它需要的所有信息都是普通的论点。 我们可以在派生类中看到这种混淆,其中……

bool isLegal(Trig trig);//override

根本没有覆盖:技术上来说,它是函数名称的重载 ,也就是说,只是具有相同名称的另一个函数。 这里没有虚拟性,没有替代。 并不需要。

因此,使该static成员函数不必在对象上调用:

static bool isValid(Shape const& shape);

最后,在更高层次的设计中,C ++构造函数和析构函数的全部机制都存在,以避免这种方法和检查。

这个想法是你……

  • 在每个构造函数中建立一个有效的对象。

  • 使对象在每种方法中均有效。

这样,对象就不会变得无效。 这种方法称为单阶段构造 ,并且使它“有效”的对象的属性称为类的类不变 应该由每个构造函数建立,并由每个方法维护。

这意味着,最终版本的isValid函数已删除 :它没有工作要做,因为该工作(正确地)由构造函数和方法完成。

好的,单阶段构造存在一些技术挑战,特别是如何在基类构造函数中进行派生类特定的初始化。 C ++常见问题解答对此进行了介绍。 阅读常见问题解答通常是个好主意。

第一个版本是正确的:

Trig::Trig(Point pointA, Point pointB, Point pointC) {..}

它将编译,但不会链接。 原因是您已声明 Shape的无参数构造函数,但未能定义它。 艾尔(Eiher)添加定义

Shape::Shape() {..}

或者,如果默认构造函数为OK,则从Shape的标头中删除声明。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM