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

时间:2011-03-19 23:36:07

标签: c++ static overloading non-static

我想打印两个不同的东西,具体取决于是使用Foo::print()静态调用函数还是从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 个答案:

答案 0 :(得分:55)

不,标准直接禁止:

  

ISO 14882:2003 C ++标准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
};
  

-end example]

     

...

此外,无论如何它都是模棱两可的,因为它可以在实例上调用静态函数:

  

ISO 14882:2003 C ++标准9.4 / 2 - 静态成员

     

s的静态成员X可能是   使用 qualified-id 引用   表达X::s;没有必要   使用类成员访问语法   (5.2.5)引用static member。一个   static成员可以参考使用   中的类成员访问语法   object-expression是哪种情况   评估。 [实施例:

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

-end example]

     

...

所以你所拥有的东西会含糊不清:

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:2003 C ++标准9.3.2 / 1 - 此指针

     

在非静止的体内(9.3)   成员函数,关键字this是一个   非左值表达式,其值为   对象的地址   该函数被调用。

答案 1 :(得分:2)

绝对不允许。我没有看到任何干净的方式实现这一目标。你想用这种方式解决的问题是什么?

答案 2 :(得分: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中创建getter和setter等,但这是一般的想法)

答案 3 :(得分:1)

您不能完全这样做,请参阅In silico's answer

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

无论如何,这不是一个好主意。你有两个非常相似的功能,完全不同的东西,这违反了良好的设计原则。