2

qml ビューアー (4.8 および 5.0 用) は次のように実装されます。

.h(eader) には次のものがあります。

class QtQuick2ApplicationViewer : public QQuickView
{
    Q_OBJECT

...

private:
    class QtQuick2ApplicationViewerPrivate *d;
};

次に、.CPP ファイルで:

class QtQuick2ApplicationViewerPrivate
{
    QString mainQmlFile;
    friend class QtQuick2ApplicationViewer;
    static QString adjustPath(const QString &path);
};

QtQuick2ApplicationViewer::QtQuick2ApplicationViewer(QWindow *parent)
    : QQuickView(parent)
    , d(new QtQuick2ApplicationViewerPrivate())
{
    connect(engine(), SIGNAL(quit()), SLOT(close()));
    setResizeMode(QQuickView::SizeRootObjectToView);

#ifdef Q_OS_ANDROID
    engine()->setBaseUrl(QUrl::fromLocalFile("/"));
#endif
}

friendここで使用する必要があるのはなぜですか?friend誰かがクラスを使用する理由はわかりません。フレンドクラスの実際の用途はありますか (誰もがなくても生きていけるエキゾチックを除いて)?

.h #インクルード

class QtQuick2ApplicationViewer : public QQuickView
{
    Q_OBJECT

public:
    explicit QtQuick2ApplicationViewer(QWindow *parent = 0);
    virtual ~QtQuick2ApplicationViewer();

    void setMainQmlFile(const QString &file);
    void addImportPath(const QString &path);

    void showExpanded();

private:
    class QtQuick2ApplicationViewerPrivate *d;
};

.cpp

#include "qtquick2applicationviewer.h"

#include <QtCore/QCoreApplication>
#include <QtCore/QDir>
#include <QtQml/QQmlEngine>

class QtQuick2ApplicationViewerPrivate
{
    QString mainQmlFile;
    friend class QtQuick2ApplicationViewer;
    static QString adjustPath(const QString &path);
};

QString QtQuick2ApplicationViewerPrivate::adjustPath(const QString &path)
{
#ifdef Q_OS_UNIX
#ifdef Q_OS_MAC
    if (!QDir::isAbsolutePath(path))
        return QString::fromLatin1("%1/../Resources/%2")
                .arg(QCoreApplication::applicationDirPath(), path);
#elif !defined(Q_OS_ANDROID)
    const QString pathInInstallDir =
            QString::fromLatin1("%1/../%2").arg(QCoreApplication::applicationDirPath(), path);
    if (QFileInfo(pathInInstallDir).exists())
        return pathInInstallDir;
#endif
#endif
    return path;
}

QtQuick2ApplicationViewer::QtQuick2ApplicationViewer(QWindow *parent)
    : QQuickView(parent)
    , d(new QtQuick2ApplicationViewerPrivate())
{
    connect(engine(), SIGNAL(quit()), SLOT(close()));
    setResizeMode(QQuickView::SizeRootObjectToView);

#ifdef Q_OS_ANDROID
    engine()->setBaseUrl(QUrl::fromLocalFile("/"));
#endif
}

QtQuick2ApplicationViewer::~QtQuick2ApplicationViewer()
{
    delete d;
}

void QtQuick2ApplicationViewer::setMainQmlFile(const QString &file)
{
    d->mainQmlFile = QtQuick2ApplicationViewerPrivate::adjustPath(file);
    setSource(QUrl::fromLocalFile(d->mainQmlFile));
}

void QtQuick2ApplicationViewer::addImportPath(const QString &path)
{
    engine()->addImportPath(QtQuick2ApplicationViewerPrivate::adjustPath(path));
}

void QtQuick2ApplicationViewer::showExpanded()
{
#if defined(Q_WS_SIMULATOR)
    showFullScreen();
#else
    show();
#endif
}
4

6 に答える 6

6

友達は友達のプライベートを調べます。もちろん、アクセス制限はまったくなくても構いませんが、一度使用すると、友好的であることは親密な状況で役立ちます。

于 2012-10-25T14:58:50.503 に答える
2
class Me;
class You {
    friend class Me;
private:
    Home _home;
    Car _car;
public:
    void bar(Me my);
};

class Me {
    Stuff _stuff;
public:
    foo(You you) {
       //If you consider me a friend
       you._home.enter(); //I can enter your `private _home`
       you._car.drive();  //I can drive your `private _car`.
    }
};

void You::bar(Me my) {
     my.stuff //this is an error because I don't consider you a friend so you can't touch my `private _stuff`.
}
于 2012-10-25T15:28:57.373 に答える
1

あなたがいつでも私を頼りにできることを知っています。友だちとはそういうもの。http://www.youtube.com/watch?v=xGbnua2kSa8

しかし、あなたは C++ のフレンド クラスについて質問していると思います。

「スコープ」の要点は、誰が別のクラスで何を見ることができるかを正確に定義することです。すべてのクラスのすべてをパブリックにすることができ、プログラムが正常にコンパイルおよび実行されるという意味で、「保護」または「プライベート」が必要である以上に「友達は必要ありません」。しかし、アイデアは、クラスのパブリック インターフェイスとは何かを正確に確立し、文書化することであり、したがって、他のクラスへの影響を考慮せずに変更することはできません。他のクラスへの影響を恐れずに再編成されました。

したがって、「友達」の要点は、次のように言うことです。ねえ、私はこのクラス X と、この別のクラス Y を持っています。一般に、他のクラスは、X がどのように仕事をしているのかを知る必要はありません。しかし、Y は X の低レベルのものと対話するため、それを確認する必要があります。したがって、私は Y を X の友達にします。同様に、顧客の投資の総額を計算する関数を (おそらくとりわけ) 持つ関数を持つ Investor クラスがあります。一般に、他のクラスは、私がその計算をどのように行うかを気にするべきではありません。それらは単に合計が必要なだけです。しかし今、私は TaxReporting クラスを持っています。このクラスは、その残高のうち、課税対象の証券がどれくらいで、非課税の証券がどれくらいあるかを知る必要があります。情報は機密であり、実際のプライバシー上の理由からアクセスを制限したいので、これらの機能を公開したくないのかもしれません。多くの場合、計算が難しいか頻繁に変更される可能性があるため、公開したくありません。また、変更時に発生する問題を制限するために、どのクラスがアクセスするかを厳密に制御したいと考えています。そこで私は、TaxReporting を友人にして、区別を行ういくつかの機能にアクセスできるようにします。

実際、私が C++ をやっていたときは、友達をめったに使いませんでした。しかし、「めったに」は「決して」ではありません。「ああ、これを公開して、他のクラスが見られるようにしなければならない」と思っている場合は、公開する代わりに友達を作る必要があります。

于 2012-10-25T15:14:24.537 に答える
0

「友達」はとても便利で、ずっと使いたいものです。

一般的な使用例は次のとおりです。

サブクラスを所有するクラスのプライベート関数をサブクラスが使用できるサブクラスを使用するクラスがあります。

class ManagedObject
{
public:
   void doStuff() { mMgr->updateManager(); }

private:
   Manager* mMgr;
};

class Manager
{
   friend ManagedObject;
public:
   ManagedObject* createManagedObject();

private:
   void updateManager() { }
};

したがって、この場合、「managedObject」を作成して処理するクラスがあります。このオブジェクトが操作されるたびに、それを作成したオブジェクトを更新する必要があります。クラスのユーザーに、「updateManager」を呼び出す必要がないことを知ってもらい、実際に呼び出した場合はコンパイル時エラーを生成する必要があります。

もう 1 つの一般的なケースは、クラス メンバーのように機能する関数があるが、何らかの理由でクラス メンバーになれない場合です。例は演算子<<です。独自の io ストリーム クラスを作成する場合、または operator<< を使用するシリアル化システムを作成する場合:

class serializedObject
{
public:
   friend Serializer& operator<< ( Serializer& s, const serializedObject& obj );
protected:
   u32 mSecretMember;
};

Serializer& operator<<( Serializer& s, serializedObject& obj )
{
    serializer << obj.mSecretMember;
    return s; 
}

この場合、シリアライゼーション関数は serializedObject のメンバーになることはできませんが、serializedObject の内部を調べてシリアライズする必要があります。演算子の RHS が LHS と同じクラスではない他の演算子 ( add など) を作成する同様のパターンが表示されます。

于 2012-10-25T15:14:35.830 に答える
-1

2) この文脈quitでは ではなくQApplication::quit()、それはslot原因ですが、 の何らかの内部信号ですengine()

于 2012-10-25T15:07:42.113 に答える