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

发布于 2024-10-24 03:34:24 字数 539 浏览 1 评论 0原文

我想打印两个不同的内容,具体取决于函数是使用 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++有同样的能力吗?

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();

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

So要识趣 2024-10-31 03:34:24

不,标准直接禁止:

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

某些函数声明不能
超载:

  • 仅返回类型不同的函数声明不能​​重载。
  • 同名、同参数类型的成员函数声明不能​​重载
    如果它们中的任何一个是静态成员函数声明(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的静态成员s可以是
使用qualified-id引用
表达式X::s;没有必要
使用类成员访问语法
(5.2.5) 引用静态成员。一个
static 成员可以使用以下方式引用
类成员访问语法,在
在这种情况下,对象表达式
评价。 [示例:

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++ 标准 9.3.2/1 – this 指针

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

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:

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 class X may be
referred to using the qualified-id
expression X::s; it is not necessary
to use the class member access syntax
(5.2.5) to refer to a static member. A
static member may be referred to using
the class member access syntax, in
which case the object-expression is
evaluated. [Example:

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.

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.

少年亿悲伤 2024-10-31 03:34:24

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

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?

七秒鱼° 2024-10-31 03:34:24

你不能完全做到这一点,请参阅 In silico 的答案

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

无论如何,这都不是一个好主意。您有两个名称非常相似的函数,它们执行完全不同的操作,这违反了良好的设计原则。

You can't do that exactly, see 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).

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.

峩卟喜欢 2024-10-31 03:34:24

答案是否定的,因为您不能根据返回类型进行重载。

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

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,但这是一般的想法)

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)

雪花飘飘的天空 2024-10-31 03:34:24

1) 如果函数返回类型不同,则方法重载中不可能进行重载。

2) 另外,如果我们在同一类下定义的函数中传递相同的参数,则它不能重载。

1) In case of different return type of functions overloading is not possible in method overloading.

2) also if we pass same parameters in the functions define under the same class then it can not be overload.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文