【问题标题】:C++ Cycle through the addresses of an objectC++ 循环遍历对象的地址
【发布时间】:2015-10-21 19:52:29
【问题描述】:

对象(非动态)是内存中的数据块。

有没有办法循环打印对象中的每个项目?

我尝试使用“this”来执行此操作,但我不断收到错误。

#include "stdafx.h"
#include <iostream>
#include "TestProject.h"

using namespace std;


class myclass {

    int someint = 10;
    double somedouble = 80000;
    int somearray[5] = {0, 1, 2, 3, 4};


public:   
    void somefunction();


};


void myclass::somefunction() {


    cout << "\n test \n" << this;

    myclass *somepointer;

    somepointer = this; 

    somepointer += 1;

    cout << "\n test2 \n" << *somepointer;
    //Error: no opperator '<<' matches these operands

}



int main() {


    myclass myobject;

    myobject.somefunction();

    return 0;
}

我猜这个错误是因为类型不匹配。但我真的想不出解决办法。是否有动态类型,或者我必须以某种方式测试类型?

【问题讨论】:

  • 除非您的类完全由指针组成,否则以 1 遍历内存不太可能将您带到下一个对象。
  • 另外...你得到“错误:没有运算符 '
  • 实际上,指针比char 大,所以它甚至不能只使用指针。你只需要char
  • 我也会看看这个stackoverflow.com/questions/15430848/… 你保证“按照声明的顺序增加地址”。但是有很多你不能保证你的课堂记忆。
  • 这个想法是循环运行它。

标签: c++ this pointer-arithmetic this-pointer


【解决方案1】:

你必须添加好友全局std::ostream operator &lt;&lt;才能显示对象的内容

#include "stdafx.h"
#include <iostream>

using namespace std;


class myclass {
    int someint;
    double somedouble;
    int somearray[5];
public: 
    myclass()
    {
        someint = 10;
        somedouble = 80000;
        somearray[0] = 0;
        somearray[1] = 1;
        somearray[2] = 2;
        somearray[3] = 3;
        somearray[4] = 4;
    }
    void somefunction();
    friend std::ostream& operator << (std::ostream& lhs, const myclass& rhs);
};


std::ostream& operator << (std::ostream& lhs, const myclass& rhs)
{
    lhs << "someint: " << rhs.someint << std::endl
        << "somedouble: " << rhs.somedouble << std::endl
        << "somearray: { ";

    for (int iIndex = 0; iIndex < 5; iIndex++)
    {
        if (iIndex == 4)
            lhs << rhs.somearray[iIndex] << " }" << std::endl;
        else
            lhs << rhs.somearray[iIndex] <<  ", ";
    }

    return lhs;
}


void myclass::somefunction() {


    cout << "\n test \n" << this;

    myclass *somepointer;

    somepointer = this; 

    somepointer += 1; // wrong pointer to object with `object + sizeof(object)` address, 
    // data probably has been corrupted

    cout << "\n test2 \n" << *somepointer; // displaying objects content
}

int main() {


    myclass myobject;

    myobject.somefunction();

    return 0;
}

当你想使用它的指针转移到对象成员时,我发布了另一个程序

#include "stdafx.h"
#include <iostream>

using namespace std;


#pragma pack (push, 1) // force data alignment to 1 byte

class myclass {
    int someint;
    double somedouble;
    int somearray[5];
public: 
    myclass()
    {
        someint = 10;
        somedouble = 80000;
        somearray[0] = 0;
        somearray[1] = 1;
        somearray[2] = 2;
        somearray[3] = 3;
        somearray[4] = 4;
    }
    void somefunction();
    friend std::ostream& operator << (std::ostream& lhs, const myclass& rhs);
};

#pragma pack (pop) // restore data alignment


std::ostream& operator << (std::ostream& lhs, const myclass& rhs)
{
    lhs << "someint: " << rhs.someint << std::endl
        << "somedouble: " << rhs.somedouble << std::endl
        << "somearray: { ";

    for (int iIndex = 0; iIndex < 5; iIndex++)
    {
        if (iIndex == 4)
            lhs << rhs.somearray[iIndex] << " }" << std::endl;
        else
            lhs << rhs.somearray[iIndex] <<  ", ";
    }

    return lhs;
}


void myclass::somefunction() {

    int* pSomeInt = (int*)this; // get someint address
    double *pSomeDouble = (double*)(pSomeInt + 1); // get somedouble address
    int* pSomeArray = (int*)(pSomeDouble + 1); // get somearray address

    std::cout << "someint: " << *pSomeInt << std::endl
        << "somedouble: " << *pSomeDouble << std::endl
        << "somearray: { ";

    for (int iIndex = 0; iIndex < 5; iIndex++)
    {
        if (iIndex == 4)
            std::cout << pSomeArray[iIndex] << " }" << std::endl;
        else
            std::cout << pSomeArray[iIndex] <<  ", ";
    }
}

int main() {


    myclass myobject;

    myobject.somefunction();

    return 0;
}

【讨论】:

  • 所以你将成员转换成变量来打印它们?
  • 没有其他方法可以正确解释输出数据。
  • 您也可以使用 void 或 char 指针,而不是使用字节中的实际成员移位来访问它们 i 指向 someint (int*)pObjPrt 的指针,指向 somedouble (double*)(pObjPrt + 4) 的指针,指向某个数组的指针 (int*)(pObjPrt + 12)
  • 有没有办法在不专门打包数据的情况下考虑填充?
  • 不,没有。这是因为编译器将类成员的数据与成员的大小对齐,在我们的例子中它具有最大的大小(8B)。所以指向 somedouble 的指针将从 pObjPrt + 8 而不是 pObjPrt + 4 开始,而 somearray 的地址将从 pObjPrt + 16 而不是 pObjPrt + 12 开始
【解决方案2】:

C++ 在设计上没有反射特性。这意味着在运行时没有通用的、与类型无关的方式来访问类型元数据(例如,如果是类及其类型,则为成员列表)。所以你想要做的事情(如果我理解正确的话)不能在 C++ 中完成。

另外,我不确定您所说的“对象(非动态)”是什么意思。所有对象都是内存中的数据块,无论是否动态分配。

【讨论】:

  • 我同意,但我很确定动态块不能保证按顺序排列。至少,如果它们是用“新”初始化的,则不会
猜你喜欢
  • 2019-04-29
  • 2020-06-09
  • 1970-01-01
  • 2014-12-04
  • 2020-04-30
  • 2017-06-12
  • 2015-10-31
  • 2014-11-30
  • 1970-01-01
相关资源
最近更新 更多