-
Notifications
You must be signed in to change notification settings - Fork 44
Expand file tree
/
Copy pathmemhacks.h
More file actions
105 lines (84 loc) · 3.44 KB
/
memhacks.h
File metadata and controls
105 lines (84 loc) · 3.44 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#pragma once
#include <ostream>
#include <string>
#include <sstream>
#include <iostream>
using namespace std;
class B;
class A {
string a_s;
int foo;
friend void printInternals(const B&);
friend void printInternals(B&);
public:
A() : a_s("It's a!"), foo(0) { }
string getAString() const { return *((const string*)((const float*)(this) + 2)); }
string getBString() const {
return *((const string*)(this + 1));
}
float getdataFloat(size_t i) { return ((float*)(this + 2) - 4)[i]; }
virtual string aboutA() const {
stringstream ss;
ss << "String A: " << a_s;
return ss.str();
}
};
class B : public A {
string b_s;
float data[7];
friend void printInternals(const B&);
friend void printInternals(B&);
public:
B() : b_s("It's b!") {
for (size_t i = 0; i < sizeof(data) / sizeof(data[0]); i++)
data[i] = (float)i * 2;
}
/// <summary>
/// Извлекает значение <see cref="B::b_s"/> из текущего объекта.
/// Подразумевается, что текущий объект на самом деле представлено классом <see cref="B"/>.
/// </summary>
/// <returns>Значение B::b_s</returns>
virtual string aboutB() {
stringstream ss;
ss << "String B: " << b_s << endl;
ss << "Data : ";
for (size_t i = 0; i < sizeof(data) / sizeof(data[0]); i++) { ss << data[i] << "; "; }
cout << endl;
return ss.str();
}
void printData2(ostream& os);
/// <summary>
/// Извлекает значения <see cref="A::a_s"/>, <see cref="B::b_s"/> и <see cref="B::data"/>
/// из текущего объекта и выводит их в текстовом виде в указанный выходной поток
/// с помощью адресной арифметики.
/// Подразумевается, что текущий объект на самом деле представлено классом <see cref="B"/>.
/// </summary>
void printData(ostream& os) {
os << "A string is '" << getAString() << " ', B string is ' " << getBString() << " ' " << endl;
for (size_t i = 0; i < sizeof(data) / sizeof(data[0]); ++i) os << getdataFloat(i) << " ";
}
};
/// <summary>
/// Извлекает значения <see cref="A::a_s"/>, <see cref="B::b_s"/> и <see cref="B::data"/>
/// из текущего объекта и выводит их в текстовом виде в указанный выходной поток
/// с помощью виртуальных функций, предусмотренных в классе <see cref="A"/>.
/// </summary>
void B::printData2(ostream& os) {
os << aboutA();
os << aboutB();
}
/// <summary>
/// Выводит на экран адреса и размеры объекта типа <see cref="B"/> и его содержимого.
/// Можно модифицировать для собственных отладочных целей.
/// </summary>
/// <param name="b">Изучаемый объект</param>
void printInternals(B& b) {
const A* a = &b, * a2 = a;
cerr << "-------------------" << endl;
cerr << "Address of b is 0x" << &b << ", address of b.a_s is 0x" << &b.a_s << ", address of b.b_s is 0x" << &b.b_s << std::endl;
cerr << "Size of A is " << sizeof(A) << ", size of B is " << sizeof(B) << endl;
cerr << "B string is '" << b.getBString() << "'" << endl;
cerr << "B data: "; b.printData(cout); cerr << endl;
cerr << "B data: "; b.printData2(cout); cerr << endl;
cerr << "-------------------" << endl;
}