未经授权的私有类成员访问会产生编译时错误而不是运行时错误?

时间:2018-04-08 14:23:43

标签: c++ exception-handling compiler-errors private-members

这是我在最近尝试从类成员的上下文中调用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");
}

错误控制台很苍白,程序输出&#34;是&#34;在例外的情况下不做任何警告的迹象。

虽然try / exception子句中的不可接受性对我来说不是很好解释,但为什么编译器不允许代码执行,是否有任何标志要为g ++强制它运行?

2 个答案:

答案 0 :(得分:0)

使用SFINAE的几次镜头和试验,extern并未导致任何光线迹象,但有一刻我想如果我使用一些oldschool C黑客试图强迫围绕这个私人区域的周围的错误?

我在这里尝试过:

class Class_
{
private:
    int b = 10;

public:
    int a ;
};
int main()
{
    Class_ Class_;
    try {
        printf("%d\n", *((&Class_.a) - 1));

    }
    catch (void* exc) {
        printf("yet, will this ever be caught? \n");
    };

}

惊喜!

不,原始的&#39;如此说&#39;私有价值是无限制地访问的,我只是试图将一个字节的地址追溯到其前身,一旦你检查了他们的成员资格class::var并且投了他们的成员资格,那么用不同类型的变量来实现就不那么难了。 typeinfo,这里的问题无论如何都可能是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("%d\n",cl->val);
    try {
        printf("%d\n", ((foo*)(cl))->var);
    }
    catch (void* e) {
        printf("Will this ever be caught ?");

    }
    return 0;
}

<强>输出:

3
2
  

结论: c ++编译器禁止编译对私有成员的传统未授权访问,如果在运行时从容器外部访问此成员,则不会抛出异常。 / p>

答案 1 :(得分:0)

总结一下你可能会误解的内容: privateprotected实际上限制了对后面变量,函数等的名称的访问。这意味着,(C之外的friendC的任何C::var)您将无法访问(名称)decltype(C::var)。如果char*有效,那可能是编译器中的错误(gcc和clang都不允许这样做)。

通常,C ++中没有内置内存保护(我确信可以使用底层操作系统的某些功能)。您始终可以将指向对象的指针强制转换为 l=1:0.01:10;y=l.^10; [xData, yData] = prepareCurveData(l,y); ft = fittype( 'poly10' ); [Fit, gof] = fit( xData, yData, ft, 'Normalize', 'on' ); 并访问对象的各个字节。这意味着,如果(你认为)你知道你在做什么,你可以访问一个类的个别成员(调用私有成员函数是具有挑战性的,我猜)。换句话说,如果你想用脚射击自己,C ++不会阻止你这样做。