C++ 用非静态函数重载静态函数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5365689/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
C++ Overload Static Function with Non-Static Function
提问by Alan Turing
I would like to print two different things depending on whether a function is called statically with Foo::print()
or from an instance of Foo foo; foo.print();
我想打印两个不同的东西,这取决于一个函数是用Foo::print()
一个实例还是从一个实例静态调用Foo foo; foo.print();
EDIT: Here is a class definition that definitely does not work, as answered by a few people already.
编辑:这是一个绝对不起作用的类定义,正如一些人已经回答的那样。
class Foo {
string bla;
Foo() { bla = "nonstatic"; }
void print() { cout << bla << endl; }
static void print() { cout << "static" << endl; }
};
However, is there a good way of achieving this effect? Basically, I would like to do:
但是,有没有什么好的方法可以达到这个效果呢?基本上,我想做:
if(this is a static call)
do one thing
else
do another thing
Phrased in another way, I know PHP can check if the *this
variable is defined or not to determine whether the function is called statically. Does C++ have the same capability?
换句话说,我知道 PHP 可以检查*this
变量是否已定义,以确定函数是否被静态调用。C++ 是否具有相同的功能?
回答by In silico
No, it is directly prohibited by the standard:
不可以,标准直接禁止:
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:
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]
...
—结束示例]
...
Besides, it would be ambiguous anyway since it's possible to call static functions on instances:
此外,无论如何它都是模棱两可的,因为可以在实例上调用静态函数:
ISO 14882:2003 C++ Standard 9.4/2 – Static members
A static member
s
of classX
may be referred to using the qualified-idexpressionX::s
; it is not necessary to use the class member access syntax (5.2.5) to refer to astatic member
. Astatic
member may be referred to using the class member access syntax, in which case theobject-expression
is evaluated. [Example:
ISO 14882:2003 C++ 标准 9.4/2 – 静态成员
可以使用qualified-id表达式引用
s
类的静态成员;没有必要使用类成员访问语法 (5.2.5) 来引用. 甲 构件可被称为使用类的成员访问语法,在这种情况下被评估。[例子:X
X::s
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]
...
—结束示例]
...
So there would be ambiguity with what you have:
所以你所拥有的东西会有歧义:
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();
}
To address your question about whether you can check what instance a member function is being called on, there is the this
keyword. The this
keyword points to the object for which function was invoked. However, the this
keyword will always point to an object i.e. it will never be NULL
. Therefore it's not possible to check if a function is being called statically or not à la PHP.
为了解决您是否可以检查正在调用成员函数的实例的问题,有this
关键字。的this
关键字指向的对象为其调用功能。但是,this
关键字将始终指向一个对象,即它永远不会是NULL
。因此,不可能检查函数是否被静态调用或不是像 PHP 那样被调用。
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.
ISO 14882:2003 C++ 标准 9.3.2/1 – this 指针
在非静态 (9.3) 成员函数的主体中,关键字
this
是一个非左值表达式,其值是调用该函数的对象的地址。
回答by Janick Bernet
It is definitely not allowed. I don't see any clean way of achieving this. What is exactly the problem that you want to solve this way?
这是绝对不允许的。我没有看到任何干净的方法来实现这一目标。您想以这种方式解决的问题究竟是什么?
回答by Brian Roach
The answer is no, because you can't overload based on a return type.
答案是否定的,因为您不能基于返回类型进行重载。
You can certainly have static methods in a class, but you can't have:
你当然可以在一个类中有静态方法,但你不能有:
static void foo();
void foo();
Because they have the same method signature.
因为它们具有相同的方法签名。
EDIT:I saw your comment saying why you wanted to do this, and that you wanted to access member variables. You'd need to do this:
编辑:我看到你的评论说你为什么要这样做,以及你想访问成员变量。你需要这样做:
static void print(Foo f);
void print();
....
static void Foo::print(Foo f)
{
int a = f.a;
// do something with a
}
(Or create getters and setters in Foo, etc, but that's the general idea)
(或者在 Foo 等中创建 getter 和 setter,但这是一般的想法)
回答by Ben Voigt
You can't do that exactly, see In silico's answer.
您不能完全做到这一点,请参阅In silico's answer。
But you can make Foo::print()
and Foo foo; print(foo);
do different things. (Define void print(Foo& foo)
in the same namespace as class Foo
, it will be found by ADL).
但是你可以制作Foo::print()
和Foo foo; print(foo);
做不同的事情。(定义void print(Foo& foo)
在与 相同的命名空间中class Foo
,它将被 ADL 找到)。
In any case, this is not a good idea. You have two functions very similar in name which do completely different things, which violates good design principles.
无论如何,这都不是一个好主意。你有两个名称非常相似的函数,它们做完全不同的事情,这违反了良好的设计原则。