C ++使用非静态函数重载静态函数

C++ Overload Static Function with Non-Static Function

根据函数是用Foo::print()静态调用还是从Foo foo; foo.print();的实例调用,我想打印两个不同的东西。

编辑:这里有一个类定义,它肯定不起作用,正如一些人已经回答的那样。

1
2
3
4
5
6
7
class Foo {
    string bla;
    Foo() { bla ="nonstatic"; }

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

然而,有没有一个很好的方法来达到这个效果?基本上,我想:

1
2
3
4
if(this is a static call)
    do one thing
else
    do another thing

换句话说,我知道PHP可以检查是否定义了*this变量,以确定是否静态调用函数。C++有相同的能力吗?


不,本标准直接禁止:

ISO 14882:2003 C++ Standard 13.1/2 – Overloadable declarations

Certain function declarations cannot
be overloaded:

  • Function declarations that differ only in the return type cannot be overloaded.
  • Member function declarations with the same name and the same parameter types cannot be overloaded
    if any of them is a static member function declaration (9.4).

...

[Example:

1
2
3
4
5
6
7
8
9
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
};

—end example]

...

此外,由于可以对实例调用静态函数,因此它还是不明确的:

ISO 14882:2003 C++ Standard 9.4/2 – Static members

A static member s of class X may be
referred to using the qualified-id
expression X::s; it is not necessary
to use the class member access syntax
(5.2.5) to refer to a static member. A
static member may be referred to using
the class member access syntax, in
which case the object-expression is
evaluated. [Example:

1
2
3
4
5
6
7
8
9
10
class process {
public:
        static void reschedule();
}
process& g();
void f()
{
        process::reschedule(); // OK: no object necessary
        g().reschedule();      // g() is called
}

—end example]

...

所以你所拥有的东西会有歧义:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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。因此,不可能检查函数是否被静态调用。

ISO 14882:2003 C++ Standard 9.3.2/1 – The this pointer

In the body of a nonstatic (9.3)
member function, the keyword this is a
non-lvalue expression whose value is
the address of the object for which
the function is called.


绝对不允许这样做。我看不出有任何干净的方法来实现这一点。你到底想用这种方法解决什么问题?


你不能完全做到这一点,请看Silico的回答。

但是你可以让Foo::print()Foo foo; print(foo);做不同的事情。(在与class Foo相同的命名空间中定义void print(Foo& foo),将由adl找到)。

无论如何,这不是个好主意。您有两个名称非常相似的功能,它们执行完全不同的操作,这违反了良好的设计原则。


答案是否定的,因为不能基于返回类型重载。

类中当然可以有静态方法,但不能有:

1
2
static void foo();
void foo();

因为它们有相同的方法签名。

编辑:我看到你的评论说你为什么要这样做,你想访问成员变量。你需要这样做:

1
2
3
4
5
6
7
8
static void print(Foo f);
void print();
....
static void Foo::print(Foo f)
{
    int a = f.a;
    // do something with a
}

(或者在foo等中创建getter和setter,但这是一般的想法)