2

一部の子 (継承クラス) が、親クラスにある特定の作業機能を認識しないようにしたいと考えています。これらをプライベートにすることは、子供たちがこれらの機能を使用できないことを意味することを理解していますが、問題はそれらを見ることです。オートコンプリートに大量の「ジャンク」が表示されるという問題を回避しようとしています。

以上のことを踏まえて、ふと思いつきました。以下のコード。問題は、secretFunc の性質が完全にはわからないということです。これはグローバル関数ですか、それとも何らかの方法で親クラスに属していますか? ヘッダーで宣言されておらず、cpp で定義されているだけです。アイデアは、親にこのようないくつかの作業関数を含めることができ、これらは子クラスから隠されるということです。これを行うためのよりエリートな方法はありますか?あったとしても、secretFunc の性質を理解したいと思います。

#ifndef PARENT_H
#define PARENT_H

class Parent
{
public:
    Parent();
    ~Parent();

private:
    void privateFunc();
protected:
    void protectedFunc();
public:
    void publicFunc();

};

#endif

#include "Parent.h"

//What is the nature of this function???
void secretFunc()
{
}

UnitTest::UnitTest()
{
}

UnitTest::~UnitTest()
{
}

void UnitTest::privateFunc()
{
}

void UnitTest::protectedFunc()
{
}

void UnitTest::publicFunc()
{
}

#ifndef CHILD_H
#define CHILD_H

#include "Parent.h"

class Child : public Parent
{
public:
    Child();
    ~Child();
};

#endif

#include "Child.h"

UnitTest::Child()
{
}

UnitTest::~Child()
{
}

//Auto complete can see private Parent functions!
//Of course, child can't use them, but it can see them.
//I wish to hide these private functions from child.

//Auto complete can see and can also use protected Parent funcitons.
//As should be...

//Auto complete can see and can also use public Parent funcitons.
//As should be...

//secetFunc should be invisible.

4

4 に答える 4

3

あなたが得るものsecretFunc()は本質的にあなたが得るものの反対ですprivateFunc()。あれは:

  • privateFunc()表示されますがアクセスできません(他のParentメソッドで呼び出すことができます)。
  • secretFunc()表示されませんが、アクセス可能です。

secretFunc()詳述すると、ヘッダーファイルに使用可能な宣言がない場合でも、のように定義された無料の関数はグローバル名前空間にあります。したがって、リンクされている他のファイルのコードは、それが正しい限り、独自の宣言を記述しParent.cppて呼び出すことができます。secretFunc()

つまり、Child.cpp含む可能性があります

void secretFunc();

上部にあるので、関数が表示され、のすべてChild.cppがを呼び出すことができますsecretFunc()

関数をオートコンプリートで非表示にするだけの場合、これは問題ではない可能性があります。ただし、非表示とアクセス不能の両方を同時に実現できます。あなたがする必要があるのはsecretFunc、グローバル名前空間から削除することです。これは、匿名の名前空間で囲むことで実行できます。

だからParent.cppあなたは書く:

namespace {
  void secretFunc() {
     // ...
  }
}

これにより、関数はファイルの外部にあるものからは見えなくなり、アクセスできなくなりParent.cppます。(上記Child.cppのように)独自の宣言を行うと、リンカーはsecretFuncグローバル名前空間でその名前の関数を見つけることができないため、エラーを生成します。

これは、次の点でプライベートメソッドとは異なることに注意してください。

  • アクセシビリティは、クラスではなく、Parent.cpp ファイル内のものに制限されています。Parent
  • のクラスメンバーではないため、オブジェクトParentへの特別なアクセスはありません(そしてポインタもありません)。Parentthis

最後にもう1つ。static匿名の名前空間で関数を囲む代わりにキーワードを使用しても同じ効果がありますが、これはC-ismです。匿名の名前空間を使用することは、それを行うための慣用的なC++の方法です。

于 2012-11-22T16:38:36.723 に答える
1

これsecretFuncはスタンドアロン関数であり、それまたはその宣言を見た人は誰でも呼び出すことができます。クラスメソッドとは異なり、それを呼び出すクラスインスタンスのメンバーにアクセスできません。

于 2012-11-22T16:18:09.510 に答える
1

プライベート メンバー関数をオート コンプリートから非表示にすることについての質問については、IDE によって異なりますが、Visual Studio を使用している場合は不可能のようです。Qt Creator を使用している場合は、それもできないようです。私はEclipseについて確信が持てませんが、それも不可能だと思います。「不可能」と言うときは、コードを変更しないと不可能だという意味です。pimplイディオムを使用して、プライベート メンバーと外部依存関係を隠すことができます。もちろん、private pimplオートコンプリートによって引き続き表示されますが、不完全なポインター型になるため、ユーザーにとってはあまり役に立たず、メンバーは 1 つだけです。

についての質問secretFuncですが、 を作成するsecretFunc staticと、Parent.cpp だけがそれを参照して使用できるようになります。現在のように、他のソース ファイルはextern void secretFunc();secretFunc.

static修飾子 ( ) を指定するとstatic void secretFunc()、その中のソース ファイルからのみ表示されます。リンカーはそれを他の翻訳単位に公開しません。

于 2012-11-22T16:20:07.363 に答える
0

プライベート仮想関数を使用でき、派生クラスでそれらをオーバーライドできます(ただし、呼び出すことはできません)。この言語機能は、彼らが言うように、狭い範囲で広く知られています。人々はそれを本番コードで使用しています。

したがって、IDEからプライベートメンバーを隠すことは逆効果のように思われます。

VSでは、プリプロセッサのちょっとしたトリックを使用して、IntelliSenseから任意のメンバーを非表示にできます。

#ifndef __INTELLISENSE__    
void ThisShouldNotBeSeen() {}
#endif

ただし、これにより、派生クラスだけでなく、あらゆる場所のIntelliSenseから非表示になります。これは、親クラス自体を開発するときに不便です。これは、多くの偽のIntelliSenseエラーと赤い下線が表示されるためです。このマクロをリリースするヘッダーファイルに追加すると便利な場合があります。

他のIDEについてはよくわかりません。

于 2012-11-22T17:26:35.203 に答える