可以在程序中更改访问说明符来更改程序的行为吗?

时间:2019-04-04 21:23:02

标签: c++ c++11

我想知道在C ++程序中是否存在任何情况,其中更改代码中的访问说明符(公共/受保护/私有)会导致该程序的行为发生变化?

3 个答案:

答案 0 :(得分:4)

模板使您可以根据成员或方法是否可访问来做不同的事情。仅作为一个随机示例,请考虑以下问题:

#include <type_traits>
#include <iostream>

struct foo_private {
    private:
        foo_private() {}
};
struct foo_public {
    public:
        foo_public() {}
};

int main() {        
    std::cout << std::is_default_constructible<foo_private>::value;
    std::cout << std::is_default_constructible<foo_public>::value;       
}

答案 1 :(得分:3)

一个有趣的示例,该示例基本上只在运行时发生,这意味着程序需要以某种方式知道一些从访问级别派生的信息:对于[except.handle]/3.2,如果异常处理程序接受明确且 > public 异常对象的类类型的基类。

http://myserver2/?PatientID=123456

此打印:

#include <iostream>

class Base {};

void test(void (*thrower)()) {
    try {
        thrower();
    } catch (Base&) {
        std::cout << "Caught a Base." << std::endl;
    } catch (...) {
        std::cout << "Not a Base?" << std::endl;
    }
}

class D1 : public Base {};
class D2 : private Base {};

int main() {
    std::cout << "Test D1" << std::endl;
    test([]() { throw D1{}; });
    std::cout << "Test D2" << std::endl;
    test([]() { throw D2{}; });
}

...即使Test D1 Caught a Base. Test D2 Not a Base? D1之间的唯一区别是访问说明关键字的更改。

答案 2 :(得分:1)

是的,如果有人SFINAE退出了该功能,则可能会发生这种情况。例如:

class Cat {
public:
    void purr() const;

public:
    void hiss() const;
};

using prefer_overload_t = int;
using backup_overload_t = long;

template <typename T>
auto react(prefer_overload_t, T const& t)
    -> decltype(t.purr())
{
    return t.purr();
}

template <typename T>
void react(backup_overload_t, T const& t)
{
    t.hiss();
}

int main() {
    Cat cat;
    react(prefer_overload_t{}, cat);
}

Live on Godbolt

如果purr函数具有公共可访问性,则会调用cat.purr()。 如果purr函数具有非公共可访问性,则会调用cat.hiss()