2

所以我有这些头文件:

形状.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 中使用过继承]

关于虚拟功能..它们的实现与普通功能有什么不同吗?[我理解行为的差异]。

4

2 回答 2

4

评论中你解释说

“我收到错误:未定义对‘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对象和右值对象作为参数:

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++ FAQ涵盖了这一点。阅读常见问题解答通常是个好主意。

于 2012-09-15T12:27:18.530 回答
1

第一个版本是正确的:

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

它会编译,但不会链接。原因是您声明了 的无参数构造函数Shape,但您没有定义它。或者添加一个定义

Shape::Shape() {..}

或者,如果默认构造函数正常,则从 Shape 的标题中删除声明。

于 2012-09-15T12:04:47.687 回答