我想打印两个不同的东西,具体取决于是使用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 ++是否具有相同的功能?
答案 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会找到它。
无论如何,这不是一个好主意。你有两个非常相似的功能,完全不同的东西,这违反了良好的设计原则。