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可以检查*this
variables是否被定义,以确定函数是否被静态调用。 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等,但是这是一般的想法)