c ++如何定义不复制数据的强制转换操作符?

时间:2012-03-12 17:57:36

标签: c++ casting operators

好吧 - 也许这是一个愚蠢的问题,演员已经固有地这样做了。

我有什么:

  • 4x4矩阵的一些外部类定义

  • 一些自己的4x4 Matrix类

这两个类只是简单地存储一个浮点数[16];

我想在我的Matrix类中定义一个强制转换操作符,以便我可以执行以下操作:

MyMatrix4x4 m;
OtherMatrix4x4(m).someFunctionDefinedInOtherMatrix4x4();
SomeFunctionThatTakesOtherMatrix4x4(OtherMatrix4x4(m));

我不希望此运算符复制任何数据 - 函数应该只在相同的float [16]数据上运行

怎么做?

3 个答案:

答案 0 :(得分:3)

  

我不希望此运算符复制任何数据 - 函数应该只在相同的float [16]数据上运行

     

我不想在堆上创建任何数据。希望这可以使用堆栈上的值 - 而且为了方便我想要一个强制转换操作符

那不会发生。 C ++的别名规则非常禁止。

您可以使用指针强制转换来“假装这是其他东西”,但您不能使用对象强制转换来执行此操作。您可以将指向堆栈对象的指针强制转换为指向对象类型的指针:

MyMatrix4x4 m;
OtherMatrix4x4 * o = (OtherMatrix4x4 *) &m;

然而,有两个问题。首先,o只会持续m。它不是一个对象;它是指向不同对象的指针。其次,这样做(通常)未定义的行为(部分原因是由于违反了别名:两个不相关的类型重叠)。哦,可能性很大。但就C ++所保证的而言,你已经离开了地图。

这种过早优化的气味。你真的认为复制16个浮点数是 大的性能问题吗?如果是,那么为什么不在代码中使用OtherMatrix4x4而不是MyMatrix4x4

答案 1 :(得分:1)

OtherMatrix4x4(m)

这不是强制转换运算符,它是转换构造函数

假设MyMatrix4x4的以下定义:

struct MyMatrix4x4
{
    float x[16];
};

以下内容应该这样做:

struct OtherMatrix4x4
{
    float* x;
    OtherMatrix4x4(MyMatrix4x4& other)
    {
       x = other.x;
    }
    void foo()
    {
       x[0] = 0;
    }
};

测试:

MyMatrix4x4 a = {{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}};
OtherMatrix4x4(a).foo();
cout << b.x[0]; //will output 0, not 1

编辑以下是您无法编辑其他矩阵的版本:

struct OtherMatrix4x4
{
    float x[16];
    void foo()
    {
        x[0] = 0;
    }
};

struct MyMatrix4x4
{
    float* x;
    operator OtherMatrix4x4()
    {
        OtherMatrix4x4 other;
        x = other.x;
        return other;
    }
};

MyMatrix4x4 m;
OtherMatrix4x4(m).foo();

答案 2 :(得分:0)

只是提出一个展示继承的不同解决方案。这些将允许您使用上面发布的代码。但是,这不是演员。

class MyMatrix4x4 {
public:
    float f;
};

class OtherMatrix4x4 : MyMatrix4x4  {
public:
    OtherMatrix4x4(MyMatrix4x4 &matrix)
    {
        f = matrix.f;
    }

    void someFunctionDefinedInOtherMatrix4x4();
};