C++类,友元运算符与外部运算符有什么区别

发布于 2024-12-27 17:36:21 字数 977 浏览 1 评论 0原文

当我们在类中定义运算符函数时,我们也在类中定义了它,那么该函数就不是类的一部分。

但当该函数位于类外部并且我们将其声明为类内部的友元但不定义它时,也会实现相同的任务。

考虑一下这段代码,它有两个相同的运算符定义,其中一个在类内部,另一个在类外部:

版本 1(类内部)

class MyClass
{
    // version 1 inside a class
    friend MyClass&& operator +(MyClass& a, MyClass& b)
    {
        return move(MyClass(a.x + b.x, a.y + b.y));
    }
    int x,y;

public:
    MyClass() {}
    MyClass(int,int){}
};

int main()
{
    MyClass a, b, c;
    c = a + b;
    cin.ignore();
    return 0;
}

版本 2(类外部)

class MyClass
{
      friend MyClass&& operator +(MyClass& a, MyClass& b);
    int x,y;

public:
    MyClass() {}
    MyClass(int,int){}
};

MyClass&& operator +(MyClass& a, MyClass& b)
{
    return move(MyClass(a.x + b.x, a.y + b.y));
}

int main()
{
    MyClass a, b, c;
    c = a + b;
    cin.ignore();
    return 0;
}

这两种方法有什么区别?

When we define an operator function inside a class an we also define it inside a class then that function is NOT part of the class.

but also the same task is achived when that function is outside the class and we declare it as a friend inside a class but not define it.

consider this code which have two identical operator definitions where one is inside the class an another ouside the class:

version 1 (inside of a class)

class MyClass
{
    // version 1 inside a class
    friend MyClass&& operator +(MyClass& a, MyClass& b)
    {
        return move(MyClass(a.x + b.x, a.y + b.y));
    }
    int x,y;

public:
    MyClass() {}
    MyClass(int,int){}
};

int main()
{
    MyClass a, b, c;
    c = a + b;
    cin.ignore();
    return 0;
}

version 2 (outside of a class)

class MyClass
{
      friend MyClass&& operator +(MyClass& a, MyClass& b);
    int x,y;

public:
    MyClass() {}
    MyClass(int,int){}
};

MyClass&& operator +(MyClass& a, MyClass& b)
{
    return move(MyClass(a.x + b.x, a.y + b.y));
}

int main()
{
    MyClass a, b, c;
    c = a + b;
    cin.ignore();
    return 0;
}

what's the difference in those two approaches?

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

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

发布评论

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

评论(2

栩栩如生 2025-01-03 17:36:21

在您的情况下,两个版本都执行相同的操作(实际上返回悬空引用,导致未定义的行为),尽管其中一个是内联的,而两个不是。

一般来说,其主体在类中定义的友元函数也可以不加限定地使用类成员(这些成员可能是静态成员,可能在基类中,因为友元函数中没有 this 指针)。

以下是标准中的相关文本(第 11.3 节 [class.friend]):

当且仅当该类是非局部类时,才可以在类的友元声明中定义函数 (9.8),
函数名称是非限定的,并且该函数具有命名空间范围。

这样的函数是隐式内联的。在类中定义的 friend 函数位于定义它的类的(词法)范围内。在类外部定义的 friend 函数不是 (3.4.1)。

In your case, both versions do the same thing (return a dangling reference, actually, causing undefined behavior), although one is inline and two isn't.

In general, the friend function whose body is defined inside the class also may use class members without qualification (those would be static members, possibly in base classes, since there's no this pointer in a friend function).

Here's the relevant text in the standard (section 11.3 [class.friend]):

A function can be defined in a friend declaration of a class if and only if the class is a non-local class (9.8),
the function name is unqualified, and the function has namespace scope.

Such a function is implicitly inline. A friend function defined in a class is in the (lexical) scope of the class in which it is defined. A friend function defined outside the class is not (3.4.1).

欢烬 2025-01-03 17:36:21

目前,您正在定义 MyClass&&运算符 +(MyClass& a, MyClass& b) 在第一个片段中两次,在第二个片段中一次。如果删除第二个定义,则两者在语义上将是等效的。

两者将执行相同的操作。在某些情况下,其中一个可能优于另一个(例如,第二个可以放置在 cpp 文件中,而第一个对于模板可能更自然)。

请注意,第一个被隐式标记为内联,第二个则不是。

(不过,您应该通过 const 引用传递 MyClass 。)

At the moment, you are defining MyClass&& operator +(MyClass& a, MyClass& b) twice in the first snippet and once in the second. If you remove the second definition, the two will be semantically equivalent.

The two will do the same thing. In some cases one may be preferred over the other (for example, the second can be placed in a cpp file and the first may be more natural with templates).

Note that the first is implicitly marked inline, the second is not.

(You should be passing MyClass by const reference, though.)

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