42

Foo::print()関数が静的に呼び出されるか、インスタンスから呼び出されるかに応じて、2つの異なるものを出力したいと思います。Foo foo; foo.print();

編集:すでに数人が答えているように、これは間違いなく機能しないクラス定義です。

class Foo {
    string bla;
    Foo() { bla = "nonstatic"; }

    void print() { cout << bla << endl; }
    static void print() { cout << "static" << endl; }
};

しかし、この効果を達成するための良い方法はありますか?基本的に、私はしたいです:

if(this is a static call)
    do one thing
else
    do another thing

別の言い方をすれば、PHPは*this変数が定義されているかどうかをチェックして、関数が静的に呼び出されているかどうかを判断できることを知っています。C ++には同じ機能がありますか?

4

5 に答える 5

63

いいえ、規格では直接禁止されています。

ISO 14882:2003C++標準13.1/2 –オーバーロード可能な宣言

特定の関数宣言はオーバーロードできません。

  • 戻り型のみが異なる関数宣言は、オーバーロードできません。
  • 同じ名前で同じパラメーター型のメンバー関数宣言は、それらのいずれかがstaticメンバー関数宣言(9.4)である場合、オーバーロードできません。

..。

[例:

class X {
    static void f();
    void f();                // ill-formed
    void f() const;          // ill-formed
    void f() const volatile; // ill-formed
    void g();
    void g() const;          // OK: no static g
    void g() const volatile; // OK: no static g
};

-例を終了]

..。

さらに、インスタンスで静的関数を呼び出すことができるため、とにかくあいまいになります。

ISO 14882:2003C++標準9.4/2 –静的メンバー

sクラスの静的メンバーは、 qualified-idXを使用して参照できます。を参照するためにクラスメンバーアクセス構文(5.2.5)を使用する必要はありません。メンバーは、クラスメンバーアクセス構文を使用して参照できます。 その場合、は評価されます。[例:X::sstatic memberstaticobject-expression

class process {
public:
        static void reschedule();
}
process& g();
void f()
{
        process::reschedule(); // OK: no object necessary
        g().reschedule();      // g() is called
}

-例を終了]

..。

したがって、あなたが持っているものにはあいまいさがあります:

class Foo
{
public:
    string bla;
    Foo() { bla = "nonstatic"; }
    void print() { cout << bla << endl; }
    static void print() { cout << "static" << endl; }
};

int main()
{
    Foo f;
    // Call the static or non-static member function?
    // C++ standard 9.4/2 says that static member
    // functions are callable via this syntax. But
    // since there's also a non-static function named
    // "print()", it is ambiguous.
    f.print();
}

メンバー関数が呼び出されているインスタンスを確認できるかどうかについての質問に答えるために、thisキーワードがあります。キーワードはthis、関数が呼び出されたオブジェクトを指します。ただし、thisキーワードは常にオブジェクトを指します。つまり、オブジェクトは決してなりませんNULL。したがって、関数が静的に呼び出されているかどうか、またはPHPで呼び出されていないかどうかを確認することはできません。

ISO 14882:2003C++標準9.3.2/1 –このポインタ

非静的(9.3)メンバー関数の本体では、キーワードthisは非左辺値式であり、その値は関数が呼び出されるオブジェクトのアドレスです。

于 2011-03-19T23:40:43.570 に答える
2

絶対に許可されていません。これを達成するための明確な方法は見当たりません。この方法で解決したい問題は正確には何ですか?

于 2011-03-19T23:41:09.097 に答える
1

リターンタイプに基づいてオーバーロードすることはできないため、答えはノーです。

クラスに静的メソッドを含めることはできますが、次のことはできません。

static void foo();
void foo();

それらは同じメソッドシグネチャを持っているからです。

編集:なぜこれを実行したいのか、メンバー変数にアクセスしたいというコメントを見ました。これを行う必要があります:

static void print(Foo f);
void print();
....
static void Foo::print(Foo f)
{
    int a = f.a;
    // do something with a
}

(または、Fooなどでゲッターとセッターを作成しますが、それが一般的な考え方です)

于 2011-03-19T23:43:53.600 に答える
1

それを正確に行うことはできません。インシリコの回答を参照してください。

しかし、あなたはさまざまなことを作りFoo::print()Foo foo; print(foo);行うことができます。void print(Foo& foo)(と同じ名前空間で定義しますclass Foo。ADLによって検出されます)。

いずれにせよ、これは良い考えではありません。名前が非常に似ている2つの関数があり、それらはまったく異なることを行います。これは、優れた設計原則に違反します。

于 2011-03-19T23:49:56.293 に答える
0

1)関数の戻りタイプが異なる場合、メソッドのオーバーロードではオーバーロードはできません。

2)また、同じクラスで定義された関数で同じパラメーターを渡す場合、オーバーロードすることはできません。

于 2021-09-17T11:09:32.803 に答える