从一个博客帖子访问私有成员:更安全的污秽由约翰内斯·绍布- litb:
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)
如何get从a对象调用函数,因为它没有在里面定义class A?
编辑:
我不明白为什么get必须有Tag作为参数而不是 …
灵感来自这个声称破坏访问控制系统的答案,我编写了以下最小版本的黑客
template<typename T>
inline T memptr{};
template<auto Val>
struct setptr
{
struct setter { setter() { memptr<decltype(Val)> = Val; } };
static setter s;
};
template<auto Val>
typename setptr<Val>::setter setptr<Val>::s{};
Run Code Online (Sandbox Code Playgroud)
然后用作
class S
{
int i;
};
template struct setptr<&S::i>;
auto no_privacy(S& s)
{
return s.*memptr<int S::*>;
}
Run Code Online (Sandbox Code Playgroud)
为什么不template struct setptr<&S::i>;违反访问控制?
访问控制统一应用于所有名称,无论名称是从声明还是表达式引用.
具体是不包括实例化?在哪种情况下,为什么不包括实例化?
勘误表:显式实例化也被归类为声明.
我使用以下类在某个函数的开头自动设置等待光标,并在函数返回时重置光标.
class WaitCursorSetter
{
public:
WaitCursorSetter() {QApplication::setOverrideCursor(Qt::WaitCursor);}
virtual ~WaitCursorSetter() {QApplication::restoreOverrideCursor();}
};
Run Code Online (Sandbox Code Playgroud)
我WaitCursorSetter在函数开始时创建一个本地对象.由于等待游标在对象的析构函数中被重置,因此当函数返回并且对象超出范围时,我不必在方法中的每个return语句之前重置游标,因为析构函数被调用.
如果编译器优化了未引用的WaitCursorSetter对象,则不起作用.我的问题是,编译器是否允许优化此对象?
在这段代码中,为什么c++编译器在编译时不直接返回1 test(),而是从内存中读取值?
struct Test {
const int x = 1;
// Do not allow initializing x with a different value
Test() {}
};
int test(const Test& t) {
return t.x;
}
Run Code Online (Sandbox Code Playgroud)
编译器输出:
test(Test const&): # @test(Test const&)
mov eax, dword ptr [rdi]
ret
Run Code Online (Sandbox Code Playgroud)
我本来期望:
test(): # @test(Test const&)
mov eax, 1
ret
Run Code Online (Sandbox Code Playgroud)
是否有任何符合标准的方法来修改 的值Test::x以包含与 不同的值1?或者是否允许编译器进行这种优化,但 gcc 和 clang 都没有实现它?
编辑:当然,您立即发现我将其作为最小示例的错误,即允许结构的聚合初始化。我使用空的默认构造函数更新了代码,以防止出现这种情况。(godbolt 上的旧代码)
基于这个讨论,我想知道函数作用域静态变量是否总是使用内存,或者是否允许编译器对其进行优化.为了说明这个问题,假设一个这样的函数:
void f() {
static const int i = 3;
int j = i + 1;
printf("%d", j);
}
Run Code Online (Sandbox Code Playgroud)
编译器很可能i会3 + 1在编译时内联函数并可能进行计算.由于这是i使用值的唯一位置,因此不需要分配任何静态内存.那么编译器是允许优化静态的,还是标准要求任何静态变量都分配了内存?
我尝试更深入地了解 Public | 之间的差异。私人 | 在 C++ 中从低级角度保护。
三者的差异在记忆中表现如何?