C ++重载静态函数与非静态函数

我想打印两个不同的东西,取决于是否用Foo::print()静态调用函数或从Foo foo; foo.print();的实例中调用函数Foo foo; 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可以检查*thisvariables是否被定义,以确定函数是否被静态调用。 C ++有相同的能力吗?

不,这是标准直接禁止的:

ISO 14882:2003 C ++标准13.1 / 2 – 可重载声明

某些函数声明不能​​被重载:

  • 仅在返回types中不同的函数声明不能​​被重载。
  • 具有相同名称和相同参数types的成员函数声明,如果它们中的任何一个是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:2003 C ++标准9.4 / 2 – 静态成员

X类的静态成员可以使用qualified-idexpression式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 } 

– 例子]

所以你会有什么不明确的地方:

 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 ++ Standard 9.3.2 / 1 – 这个指针

在非静态(9.3)成员函数的主体中,关键字this是一个非左值expression式,其值是调用该函数的对象的地址。

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

你无法做到这一点,请参阅硅计算机的答案 。

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

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

答案是否定的,因为你不能基于返回types进行重载。

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

 static void foo(); void foo(); 

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

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

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

(或者在Foo中创buildgetter和setter等,但是这是一般的想法)