【问题标题】:Calling Base Class Functions with Inherited Type使用继承类型调用基类函数
【发布时间】:2013-06-27 21:06:16
【问题描述】:

我无法准确描述我想说的内容,但我想使用具有继承类型的基类函数。就像我想声明“Coord3D operator + (Coord3D);”在一个类中,但如果我将它与 Vector3D 操作数一起使用,我希望它返回 Vector3D 类型而不是 Coord3D。

使用下面这行代码,我添加了两个 Vector3D 并得到一个 Coord3D 作为回报,正如 typeid().name() 函数告诉我的那样。如何重新组织我的课程以便在返回时获得 Vector3D?

#include <iostream>
#include <typeinfo>
using namespace std;

class Coord3D
{
public:
        float x, y, z;
        Coord3D (float = 0.0f, float = 0.0f, float = 0.0f);
        Coord3D operator + (Coord3D &);
};

Coord3D::Coord3D (float a, float b, float c)
{
        x = a;
        y = b;
        z = c;
}

Coord3D Coord3D::operator+ (Coord3D &param)
{
        Coord3D temp;
        temp.x = x + param.x;
        temp.y = y + param.y;
        temp.z = z + param.z;
        return temp;
}

class Vector3D: public Coord3D
{
public:
        Vector3D (float a = 0.0f, float b = 0.0f, float c = 0.0f)
        : Coord3D (a, b, c) {};
};

int main ()
{
        Vector3D a (3, 4, 5);
        Vector3D b (6, 7, 8);
        cout << typeid(a + b).name();
        return 0;
}

【问题讨论】:

  • 您希望在这里发生什么以及您希望发生什么
  • 我希望 Vector3D 能够通过使用从 Coord3D 派生的函数相互添加,但是当它们添加时,它们会变成 Coord3D 而不是 Vector3D。
  • 您必须在Vector3D 中定义一个operator+,它返回一个Vector3D 而不是Coord3D
  • 你能在 Vector3D 中创建一个 operator+ 来调用基类吗?
  • 所以我必须创建一个全新的函数,而不是基于 Coord3D 的函数?还有其他方法吗,因为第一种方法真的很冗长,有点违背 OOP 的目的。

标签: c++ class function inheritance


【解决方案1】:

您想要的功能在基类中,但它返回一个基类(这是有道理的,因为Coord3D 不知道Vector3D 是什么)。如果您坚持不为Vector3D 重写operator+()(如果您打算进行乘法等,我认为这是公平的),您可以在Vector3D 类中创建一个复制构造函数,该类可以构造一个@ 987654327@ 来自Coord3D 结果。

class Vector3D: public Coord3D
{
public:
        Vector3D (float a = 0.0f, float b = 0.0f, float c = 0.0f)
        : Coord3D (a, b, c) {};

        Vector3D (const Coord3D& param){ new ((Coord3D*)this) Coord3D(param); }
};

int main ()
{
        Vector3D a (3, 4, 5);
        Vector3D b (6, 7, 8);
        Vector3D c = a + b;
        cout << typeid(c).name();
        Sleep(1000);
        return 0;
}

【讨论】:

  • 嗯,那个“新”不是会像疯了一样泄漏内存吗?嗯,或者是placement_new,一切都很好。
  • 实际上并没有分配更多空间;构造函数已经在内存中为Vector3D 对象创建了一个漂亮的小槽,看起来像[Coord3D Vector3D]。基本上,基类与内存中的派生类连接。使用新位置,我们告诉它将添加结果的Coord3D 放入[Coord3D Vector3D] 槽内的基类位置。
  • @Aggieboy 你确定吗?现在堆上有三个浮点数,它们将被复制到堆栈中;所以堆上的三个浮点数现在是悬空指针。如果我错了,请纠正我。
  • @rwols 看看this reference。此处适用的版本是 (3) placement,它明确表示placement new 只返回ptr(不分配存储空间)。placement new 返回的指针就是@ 987654334@。在我的代码中,堆上没有分配任何内容,因此没有悬空指针。
猜你喜欢
  • 2013-03-30
  • 1970-01-01
  • 2011-01-08
  • 1970-01-01
  • 2018-03-31
  • 2021-12-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多