是否可以覆盖 C++ 中指向对象的指针的数组访问运算符?

发布于 2024-08-02 22:14:31 字数 1411 浏览 5 评论 0原文

我正在尝试对代码进行一些重构,但遇到了问题。该程序有一个数据管理器,它以 void* 的形式返回指向结构数组的指针。其中一种新数据类型不再具有指向结构数组的单个指针,而是具有两个指向数字数组的指针。问题在于,所有处理代码都是通过访问所有记录类型通用的 array[index].qwTimestamp 和 array[index].snSample 来完成的。

我认为像下面这样重写数组访问运算符( [] )可能会解决问题:

class ADRec {

public:
    ADRec(unsigned __int64* ts, __int32* data, unsigned index = 0): mTimestamps(ts), mDataPoints(data), mIndex(index) {

        qwTimeStamp = mTimestamps[mIndex];
        snSample = mDataPoints[mIndex];

    }
    ADRec operator[](unsigned i) {
        return ADRec(mTimestamps, mDataPoints, i);

    }
    unsigned __int64 qwTimeStamp;
    __int32 snSample;

private:
    unsigned __int64* mTimestamps;
    __int32* mDataPoints;
    unsigned mIndex;
};

如果您使用对象,此方法可以正常工作:

unsigned __int64 ts[] = { 2, 3, 4, 5};
__int32 data[] = {4, 6, 8, 10};

ADRec tmp =  ADRec(ts, data, 0);

ASSERT(tmp[0].qwTimeStamp == 2);
ASSERT(tmp[0].snSample == 4);
ASSERT(tmp[1].qwTimeStamp == 3);
ASSERT(tmp[1].snSample == 6);

但如果您使用指向对象的指针,则失败:

unsigned __int64 ts[] = { 2, 3, 4, 5};
__int32 data[] = {4, 6, 8, 10};

ADRec* tmp =  new ADRec(ts, data, 0);

ASSERT(tmp[0].qwTimeStamp == 2);
ASSERT(tmp[0].snSample == 4);
ASSERT(tmp[1].qwTimeStamp == 3); //fails
ASSERT(tmp[1].snSample == 6); //fails

C++ 正在索引调用 tmp[1] 时的指针,从而指向随机内存。

是否可以重写 C++ 从对象指针索引的方式,或者可以实现相同目标的其他机制?

I'm trying to do some refactoring of code, and have run into a problem. The program has a data manager that returns pointers to arrays of structures as a void*. One of the new types of data, instead of having a single pointer to an array of structures, has two pointers to arrays of numbers. The problem is that all the processing code is done by accessing array[index].qwTimestamp and array[index].snSample which is common to all record types.

I thought that doing an override of the array access operator( [] ) like the following might solve the problem:

class ADRec {

public:
    ADRec(unsigned __int64* ts, __int32* data, unsigned index = 0): mTimestamps(ts), mDataPoints(data), mIndex(index) {

        qwTimeStamp = mTimestamps[mIndex];
        snSample = mDataPoints[mIndex];

    }
    ADRec operator[](unsigned i) {
        return ADRec(mTimestamps, mDataPoints, i);

    }
    unsigned __int64 qwTimeStamp;
    __int32 snSample;

private:
    unsigned __int64* mTimestamps;
    __int32* mDataPoints;
    unsigned mIndex;
};

This approach works fine if you are using an object:

unsigned __int64 ts[] = { 2, 3, 4, 5};
__int32 data[] = {4, 6, 8, 10};

ADRec tmp =  ADRec(ts, data, 0);

ASSERT(tmp[0].qwTimeStamp == 2);
ASSERT(tmp[0].snSample == 4);
ASSERT(tmp[1].qwTimeStamp == 3);
ASSERT(tmp[1].snSample == 6);

But fails if you use a pointer to an object:

unsigned __int64 ts[] = { 2, 3, 4, 5};
__int32 data[] = {4, 6, 8, 10};

ADRec* tmp =  new ADRec(ts, data, 0);

ASSERT(tmp[0].qwTimeStamp == 2);
ASSERT(tmp[0].snSample == 4);
ASSERT(tmp[1].qwTimeStamp == 3); //fails
ASSERT(tmp[1].snSample == 6); //fails

C++ is indexing off of the pointer when tmp[1] is called, and thus pointing to random memory.

Is it possible to override the way C++ indexes off of a pointer to an object, or some other mechanism that would accomplish the same goal?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

云归处 2024-08-09 22:14:31

不,这是不可能的 - 指针被认为是内置类型,因此不能重载其运算符。但是,您当然可以
创建智能指针类(行为类似于指针,但具有附加功能的类)并重载其运算符 - 例如,查看编译器的 std::auto_ptr 实现。

No, it isn't possible - pointers are considered to be of a built-in type and so cannot have their operators overloaded. However, you can certainly
create smart pointer classes (classes that act like pointers, but with added abilities) and overload their operators - take a look at your compiler's implementation of std::auto_ptr, for example.

酒废 2024-08-09 22:14:31

首先尝试取消引用指针:

ADRec* tmp =  new ADRec(ts, data, 0);

ASSERT(tmp[0][1].qwTimeStamp == 3);
// or
ASSERT((*tmp)[1].qwTimeStamp == 3);

Try dereferencing the pointer first:

ADRec* tmp =  new ADRec(ts, data, 0);

ASSERT(tmp[0][1].qwTimeStamp == 3);
// or
ASSERT((*tmp)[1].qwTimeStamp == 3);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文