未经授权的私有类成员访问会产生编译时错误而不是运行时错误?
Unauthorized private Class-member access yields a compile-time error rather than a run-time error?
这是我最近尝试从类成员的上下文中摆弄private
调用时遇到的问题:
#include <iostream>
#include <exception>
class TestClass {
private: int var;
};
int main() {
TestClass test;
try {
test.var;
}
catch( std::exception& e) {
std::cout << "why does this not occur ?";
}
return 0;
}
该错误是合理的error: ‘int TestClass::var’ is private within this context test.var;
因此我尝试将调用包装在模板类中以避免错误被智能感知。
#include <iostream>
#include <exception>
class TestClass {
private:
int var;
};
template <class t>
void foo() {
t cl;
try {
cl.var;
}
catch (std::exception& e) {
std::cout << "why does this not occur ?";
}
return;
}
int main() {
foo<TestClass>();
return 0;
}
这种对这个糟糕的私有变量区域的蹩脚访问尝试总是会导致一些编译时违规错误,SFINAE
getarround 似乎没有解决任何问题,我试图远程嗅探Class::var
类型的可访问性总是使用模板:
#include <iostream>
#include <exception>
#include <type_traits>
#include <cstdint>
class TestClass
{
private:
int var;
};
template <class C>
int hasmember() {
int ret=0;
try {
ret= std::is_same<decltype(C::var), int>::value;
}
catch (std::exception& e)
{
std::cout << "why does this not occur ?";
}
return ret;
}
int main() {
TestClass cl;
printf("%s", hasmember<TestClass>()?"yes":"no");
}
错误控制台是苍白的,程序输出"yes",不会在异常上下文中捕获任何内容。
虽然它在try/exception子句中的不可拦截性对我来说不能很好地解释,为什么编译器不允许代码执行,并且是否有任何标志可以引发g ++强制它运行?
很少使用SFINAE
进行射击和试验,extern
没有导致任何光明的迹象,但一会儿我想如果我使用一些老式的 C hack 来尝试在这个私人区域的周边强制一个赛格故障怎么办?
这是我尝试过的:
class Class_
{
private:
int b = 10;
public:
int a ;
};
int main()
{
Class_ Class_;
try {
printf("%dn", *((&Class_.a) - 1));
}
catch (void* exc) {
printf("yet, will this ever be caught? n");
};
}
惊喜!
不,原始的"所谓的"私有值是不受限制地访问的,我只是试图将地址向后跟踪一个字节以获得其前身,一旦您检查它们的成员资格class::var
并投射它们的类型信息,使用不同类型的变量并不难实现,这里的问题是这无论如何C++类结构中的安全效率低下?C 在与 C++ 一起使用时是否被认为是不安全的,以及如何保护这个私有区域,强制将 EIP 传导到异常处理程序的分段错误?
注意:在这种情况下,valgrind 报告崩溃的可能性更大,我没有尝试,但我希望有人确认。
模拟类型:
通过类类型模拟,我可以访问另一个类的私有成员,其核心略有不同,没有任何证据表明抛出异常,体验如下:
#include <stdio.h>
class foo {
public:
int var=0;
int val=1;
};
class bar {
int var=2;
public:
int val=3;
};
int main()
{
bar* cl;
cl = new bar();
printf("%dn",cl->val);
try {
printf("%dn", ((foo*)(cl))->var);
}
catch (void* e) {
printf("Will this ever be caught ?");
}
return 0;
}
输出:
3
2
结论:C++ 编译器禁止编译对私有成员的传统未经授权的访问,但如果在运行时从其容器外部访问此成员,它不会引发异常。
总结一下你可能误解的地方:private
和protected
实质上限制了对后面变量、函数等名称的访问。这意味着,(在C
或任何friend
之外C
)您将无法访问(名称)C::var
。如果decltype(C::var)
工作,那可能是编译器中的错误(gcc 和 clang 都不允许这样做)。
通常,C++中没有内置内存保护之类的东西(我确信可以使用底层操作系统的某些功能)。您将始终可以投射指向对象的指针,以char*
和访问对象的各个字节。这意味着,如果(你认为)你知道你在做什么,你可以访问一个类的单个成员(我猜调用私有成员函数具有挑战性)。换句话说,如果你想搬起石头砸自己的脚,C++不会阻止你这样做。
- 在同一模拟中使用静脉和静脉_ inet内容时出现运行时错误
- 对单向链表进行排序时出现运行时错误
- C++在使用std::multimap时出现运行时错误的几率很小
- 迭代二维矢量时发生运行时错误
- 使用纯 CMake 构建 SFML 时出现运行时错误
- QT C++防止关闭应用程序时出现运行时错误
- 使用 SET(C++) 检查两个给定字符串是否是字谜时出现运行时错误
- 运行 libpng 应用程序时出现运行时错误
- 提取 try-catch 时出现运行时错误
- 使用向量将给定表达式转换为波兰表示法时出现运行时错误
- 如何修复分段错误运行时错误
- C++,弹出调试断言失败窗口,我得到矢量迭代器不兼容的错误运行时
- 将输入输入到 c++ 数组时出现运行时错误
- 在虚幻引擎中引用外部库时出现运行时错误
- 在 std::map 中使用结构作为值时出现运行时错误
- 为什么在C 类构造函数的正确编译后发生运行时错误
- 尝试打印链表时出现运行时错误
- C++中的堆栈:切换"or"条件时出现运行时错误
- 在 Ubuntu 15.10 上使用 g++-4.9 编译时出现运行时错误 [abi:cxx11]
- GTKmm3(GTK+3 C++)编译,但运行时抛出GLib GIO CRITICAL错误