2

私はこのコードを勉強しています:

#include <iostream>

class A
{
public:
    A() {};

    void fox(A& otherA) { otherA.hello(); }

protected:
    void hello() {std::cout << "hello" << std::endl;}
};

A a1,a2;

int main(void)
{
    a1.fox(a2);
    a1.hello();
}

a1.fox(a2)そして、言うことはコンパイルされず、言うことはどのようにコンパイルされるかについて少し混乱してa1.hello()います。クラス内から保護されたプライベート関数を呼び出すことはできますが、otherAオブジェクトでそれを実行できるようにすることは、それ自体のメンバー内から呼び出すことを認識しなければならないことを意味するため、壊れると想定していました。クラス。なぜ/どのようにこれが機能するのですか?

4

3 に答える 3

6

Protected はインスタンスごとのアクセス制御ではなく、クラスごとのアクセス制御です。

main()(どのクラスにもありません)どのクラスのプライベートまたは保護されたメソッドもまったく呼び出すことができません。したがって、呼び出しに失敗しますa1.hello()

A::fox(A&)一方、の実装はクラス内にあるAため、それ自体とクラスの他のインスタンスの両方で、プライベート メソッドと保護されたメソッドを呼び出すことができます。

于 2013-05-02T02:50:22.323 に答える
0

Aが を呼び出しているためですotherA.hello();。それを呼び出したり、直接コーディングしprivateたりすることはできませんが、 の子孫 (それ自体を含む) は を呼び出すことができます(子孫は のデータ/メソッドにはアクセスできませんが、 のデータ/メソッドにはアクセスできます)。関連して、の他のインスタンスのデータ/メソッドにもアクセスできます(これは一般に、コピー コンストラクターと代入演算子がどのように機能するかです)。protectedAAAAprivateAAprivateAprivateA

実際、いくつかの非常に強力な OO 概念の作成を可能にするのは、protected内でコードを使用する機能です。classそうは言っても、可能な場合でも内部オブジェクトのprivateまたはprotectedメソッドを呼び出すのは乱用だと思いますが、それらを自分自身に対して直接使用することは、利便性ではなく設計によるものです。

C++ では、項目を実装としてマークし、実装を提供しないことで、 classes (またはs については s) の抽象的な実装を提供できます。structvirtual

class A
{
public:
    void set_value(const std::string &value)
    {
        if (is_valid(value))
        {
            this->value = value;
        }
    }

    const std::string &get_value() const
    {
        return value;
    }
protected:
    virtual boolean is_valid(const std::string &value) const = 0;
private:
    std::string value;
}

それで

class B : public A
{
protected:
    virtual boolean is_valid(const std::string &value) const
    {
        return value != "abc";
    }
}

これは機能を継承するように設定されており、それが提供されることを想定して構築されていることに注意してくださいA(上記の例は実際には多くのユーティリティを提供していませんが、私の言いたいことを示しています)。

于 2013-05-02T02:49:52.073 に答える
0

C++ のアクセス制御はクラス レベルです。インスタンスレベルではありません。

otherAコンパイラは、実際に同じインスタンスかどうかを判断できない可能性があります。このようなアクセス制御を提供するためにインスタンスの ID を実際に判別するには、ランタイム サポートが必要です。

これがもたらすパフォーマンスの問題とは別に、C++ の目的は、実行時ではなくコンパイル時にエラーをキャッチすることです。stroustrup が言うように、データのカプセル化と型安全機能は、誰かが不正行為を行うのを防ぐことはできません (プログラムが割り当てられたすべてのメモリへの仲介されないアクセスを持っている場合)。

では、実行時チェックなしのソリューションで解決できるのはなぜでしょうか。クラスの実装者として、自分の家を奪うことはないからです。

于 2013-05-02T09:14:47.323 に答える