我有以下课程:
class BritneySpears
{
public:
int getValue() { return m_value; };
private:
int m_value;
};
Run Code Online (Sandbox Code Playgroud)
哪个是外部库(我无法更改).我显然无法改变它的价值m_value,只能读它.即使是衍生BritneySpears也行不通.
如果我定义以下类,该怎么办:
class AshtonKutcher
{
public:
int getValue() { return m_value; };
public:
int m_value;
};
Run Code Online (Sandbox Code Playgroud)
然后做:
BritneySpears b;
// Here comes the ugly hack
AshtonKutcher* a = reinterpret_cast<AshtonKutcher*>(&b);
a->m_value = 17;
// Print out the value
std::cout << b.getValue() << std::endl;
Run Code Online (Sandbox Code Playgroud)
我知道这是不好的做法.但出于好奇:这是否有效?它是否定义了行为?
奖金问题:你有没有必要使用这样一个丑陋的黑客?
我们臭名昭着的litb有一篇关于如何规避访问检查的有趣文章.
这个简单的代码充分证明了这一点:
#include <iostream>
template<typename Tag, typename Tag::type M>
struct Rob {
friend typename Tag::type get(Tag) {
return M;
}
};
// use
struct A {
A(int a):a(a) { }
private:
int a;
};
// tag used to access A::a
struct A_f {
typedef int A::*type;
friend type get(A_f);
};
template struct Rob<A_f, &A::a>;
int main() {
A a(42);
std::cout << "proof: " << a.*get(A_f()) << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
其中编译和运行(输出42)与GCC 4.3.4,GCC 4.5.1,GCC 4.7.0(见user1131467的评论),并与锵3.0和科莫ç编译/ …
我有重载的功能,如:
void f(int)
void f(int, int)
void f(int, float)
Run Code Online (Sandbox Code Playgroud)
如何编译它,以便我可以看到错位的输出?就像是:
void f(int) should show: ?f@@YAXH@Z(int)
Run Code Online (Sandbox Code Playgroud)
例如,要查看我们使用的预处理器输出-E,汇编器输出-s,它是什么名称错位输出?
PS:平台是Linux
编辑:
通过这里的答案我们去:
void func(int);
void func(int, int);
void func(void);
void func(char);
[root@localhost ~]# cat a.map | grep func
0x0804881a _Z4funcc
0x08048790 _Z4funcv
0x080487be _Z4funcii
0x080487ec _Z4funci
Run Code Online (Sandbox Code Playgroud) 说我有以下内容:
class A {
private:
int a;
virtual int f() {return a;}
public:
A(int t) {a = t;}
};
Run Code Online (Sandbox Code Playgroud)
现在,int A::f()如果给出指向A对象的指针,如何访问?我知道如何得到一个!
void main () {
A* x = new A(5);
cout << ((int*)x)[2]; // returns 5;
}
Run Code Online (Sandbox Code Playgroud)
但现在确定如何运行A :: f().
更新:我知道这不是一个好的设计,并且私有应该被隐藏.问题只是要知道如何将类放入编译器的内存中.