C++:允许受保护的类成员而不是私有成员访问

  • 本文关键字:成员 访问 受保护 C++ c++ class
  • 更新时间 :
  • 英文 :


我知道你可以用继承来做到这一点,但除了'is a'的情况之外,你打算使用继承。我也知道有朋友,但他们也允许访问私人成员。

有没有办法做到这一点(允许访问受保护的类成员而不是私人成员)?

为了改写这个问题,我有 1 类和 2 类。我希望 2 类能够访问 1 类的受保护成员和公共成员,但不能访问 1 类的私有成员。我该怎么做?

它并不优雅,但这可能对你有用:

class B;
class A {
protected:
    int x;
private:
    int y;
};
class A_wrapper : public A {
    friend B;
};

class B {
public:
    A_wrapper a;
    int foo() {
        a.x;   // Ok
        a.y;   // Compiler error!
    }
};

很久以前,在这个网站上,我提出了一个使用 Key 的方案。这个想法是,主类记录接口的哪些部分可以公开访问,哪些部分需要一个密钥,然后向需要它的人授予对密钥的友谊。

class Key { friend class Stranger; Key() {} ~Key() {} };
class Item {
public:
    void everyone();
    void restricted(Key);
private:
};

现在,只有Stranger可以使用 restricted 方法,如下所示:

class Stranger {
public:
    void test(Item& i) {
        Key k;
        i.restricted(k);
    }
    Key key() { return Key(); }
    Key _key;
};
class Other {
    void test(Item& i) {
        Stranger s;
        i.restricted(s.key()); // error: ‘Key::~Key()’ is private
                               // error: within this context
    }
    void test2(Item& i) {
        Stranger s;
        i.restricted(s._key); // error: ‘Key::~Key()’ is private
                              // error: within this context
                              // error:   initializing argument 1 of ‘void Item::restricted(Key)’
    }
};

这是一个非常简单的方案,它允许更细粒度的方法,即完整的友谊。

Oli 提供了一个更接近的解决方案(+1),但你也可以使用选择性的朋友来处理它:

#include <iostream>
class t_thing;
class t_elsewhere {
public:
    void print(const t_thing& thing);
};
class t_thing {
public:
    class t_selective_friend {
        static int Prot(const t_thing& thing) {
            return thing.prot;
        }
        friend class t_elsewhere;
    };
public:
    int publ;
protected:
    int prot;
protected:
    int priv;
};
void t_elsewhere::print(const t_thing& thing) {
    std::cout << t_thing::t_selective_friend::Prot(thing) << std::endl;
}
int main() {
    t_thing thing;
    thing.publ; /* << ok */
    thing.prot; /* << error */
    thing.priv; /* << error */
    t_elsewhere().print(thing); /* << ok */
    return 0;
}

有时这种冗长/控制是好的...

最新更新