C++ 打印基类和继承类的内存内容

C++ 打印基类和继承类的内存内容,c++,c++03,C++,C++03,我正在尝试添加一个print()成员函数,该函数将输出对象的内存内容,如下所示: #include <iostream> #include <string> class A { public: virtual std::string print() { std::string s; s.append(reinterpret_cast<char*>(this), 0, sizeof(A)); retur

我正在尝试添加一个print()成员函数,该函数将输出对象的内存内容,如下所示:

#include <iostream>
#include <string>

class A {
 public:
    virtual std::string print() {
        std::string s;
        s.append(reinterpret_cast<char*>(this), 0, sizeof(A));
        return s;
    }
};

class B : public A {
 public:
    B() : a('a') {}
    char a;
};

int main() {
    A a;
    B b;
    std::cout << "A \"" << a.print() << "\"\n";
    std::cout << "B \"" << b.print() << "\"\n";
    return 0;
}
#包括
#包括
甲级{
公众:
虚拟标准::字符串打印(){
std::字符串s;
s、 追加(重新解释(this),0,sizeof(A));
返回s;
}
};
B类:公共A{
公众:
B():a('a'){}
字符a;
};
int main(){
A A;
B B;

std::cout要安全地执行此操作,您必须覆盖B的虚拟函数:

std::string print() override {
    std::string s;
    s.append(reinterpret_cast<char*>(this), 0, sizeof(B));
    return s;
}
std::string print()覆盖{
std::字符串s;
s、 追加(重新解释cast(this),0,sizeof(B));
返回s;
}
为什么?因为你不能确定A和B有相同的地址(例如,如果有)


如果您喜欢这种转储函数,为了减少代码,您可以使用模板并在每次重写中调用模板。

要安全地执行此操作,您必须为B重写虚拟函数:

std::string print() override {
    std::string s;
    s.append(reinterpret_cast<char*>(this), 0, sizeof(B));
    return s;
}
std::string print()覆盖{
std::字符串s;
s、 追加(重新解释cast(this),0,sizeof(B));
返回s;
}
为什么?因为你不能确定A和B有相同的地址(例如,如果有)

如果您喜欢这种转储函数,为了减少代码,可以使用模板并在每次重写中调用模板。

首先,您可以
#包括

现在您可以将对象强制转换为uint8_t,并通过for循环(size=sizeof(object))对其进行迭代

通过printf将其十六进制值打印到stdin:

printf("%hu", val[i]);
首先,你可以
#包括

现在您可以将对象强制转换为uint8_t,并通过for循环(size=sizeof(object))对其进行迭代

通过printf将其十六进制值打印到stdin:

printf("%hu", val[i]);
如何打印整个长度的B

您可以考虑在类层次结构中链接打印方法。

您的计划无法处理不可打印的值。我也看不到“十六进制”转换。但是,假定您的转换为char*可以满足您的需要

class A {
public:
   virtual std::string print() {
       std::string s;
       s.append(reinterpret_cast<char*>(this), 0, sizeof(A));
       return s;
   }
};

class B : public A {
public:
   B() : a('a') {}
   char a;

   virtual std::string print() {
       std::string s = A::print(); // get A contents
       s.append(reinterpret_cast<char*>(this), 0, sizeof(B));
       return s;
   }
};
如何打印整个长度的B

您可以考虑在类层次结构中链接打印方法。

您的计划无法处理不可打印的值。我也看不到“十六进制”转换。但是,假定您的转换为char*可以满足您的需要

class A {
public:
   virtual std::string print() {
       std::string s;
       s.append(reinterpret_cast<char*>(this), 0, sizeof(A));
       return s;
   }
};

class B : public A {
public:
   B() : a('a') {}
   char a;

   virtual std::string print() {
       std::string s = A::print(); // get A contents
       s.append(reinterpret_cast<char*>(this), 0, sizeof(B));
       return s;
   }
};

使用带有非虚拟函数的模板基

template<class T> class PrintMe
{
    public:

         std::string print() const
         {
               std::string s;
               s.append(reinterpret_cast<char*>(this), 0, sizeof(T));
               return s;
         };
};

class A: public PrintMe<A>
{
     // whatever
};

class B: public PrintMe<B>
{

};

//   and in code which uses it

std::cout << some_b.print();

请注意,这完全避免了虚拟函数分派,而是依赖于编译时标识的对象类型。

使用带有非虚拟函数的模板基

template<class T> class PrintMe
{
    public:

         std::string print() const
         {
               std::string s;
               s.append(reinterpret_cast<char*>(this), 0, sizeof(T));
               return s;
         };
};

class A: public PrintMe<A>
{
     // whatever
};

class B: public PrintMe<B>
{

};

//   and in code which uses it

std::cout << some_b.print();

请注意,这完全避免了虚拟函数分派,而是依赖于编译时识别的对象的类型。

您需要一个非虚拟函数来调用Thy您需要一个非虚拟函数来调用Thy是的,我知道这一点,但我想要一些设置并忘记的东西……是的,我知道这一点,但我想这样做设置并忘记的方法…
std::uint8\u t
充其量是真正的“字节表示”类型的typedef
[un/signed]char
,最坏的情况是另一种类型,它没有与
char
系列相同的特权。只需使用
无符号char
std::uint8\u t
充其量是真正的“字节表示”类型的typedef
[un/signed]char
,最坏的情况是另一种类型,它没有与
char
系列相同的特权。只需使用
无符号char