gpt4 book ai didi

c++ - 以自身为引用构造对象?

转载 作者:可可西里 更新时间:2023-11-01 17:11:01 32 4
gpt4 key购买 nike

我刚刚意识到这个程序可以编译和运行(gcc 版本 4.4.5/Ubuntu):

#include <iostream>
using namespace std;

class Test
{
public:
// copyconstructor
Test(const Test& other);
};

Test::Test(const Test& other)
{
if (this == &other)
cout << "copying myself" << endl;
else
cout << "copying something else" << endl;
}

int main(int argv, char** argc)
{
Test a(a); // compiles, runs and prints "copying myself"
Test *b = new Test(*b); // compiles, runs and prints "copying something else"
}

我不知道为什么这甚至可以编译。我假设(就像在 Java 中一样)在调用方法/构造函数之前评估参数,所以我怀疑这种情况必须由语言规范中的某些“特殊情况”涵盖?

问题:

  1. 有人可以解释一下吗(最好是引用规范)?
  2. 允许这样做的理由是什么?
  3. 它是标准 C++ 还是特定于 gcc 的?

编辑 1:我刚刚意识到我什至可以写 int i = i;

编辑 2:即使使用 -Wall-pedantic,编译器也不会提示 Test a(a);

编辑 3:如果我添加一个方法

Test method(Test& t)
{
cout << "in some" << endl;
return t;
}

我什至可以在没有任何警告的情况下执行 Test a(method(a));

最佳答案

这个“被允许”的原因是因为规则说标识符范围在标识符之后立即开始。在这种情况下

int i = i;

RHS i 在 LHS i“之后”,所以 i 在范围内。这并不总是坏事:

void *p = (void*)&p; // p contains its own address

因为可以在不使用变量值的情况下对变量进行寻址。在 OP 的复制构造函数的情况下,不会轻易给出错误,因为绑定(bind)对变量的引用不需要初始化变量:它等同于获取变量的地址。合法的构造函数可以是:

struct List { List *next; List(List &n) { next = &n; } };

你看到的参数只是被处理,它的值没有被使用。在这种情况下,自引用实际上是有意义的:列表的尾部由自引用给出。实际上,如果您将“next”的类型更改为引用,则别无选择,因为您不能像对指针那样轻松地使用 NULL。

像往常一样,问题是倒退的。问题不是为什么变量的初始化可以引用自身,问题是为什么它不能向前引用。 [在 Felix 中,这是可能的]。特别是,对于与变量相反的类型,缺乏转发引用的能力是非常糟糕的,因为它阻止了递归类型的定义,而不是通过使用不完整的类型,这在 C 中就足够了,但在 C++ 中就不够了,因为存在模板。

关于c++ - 以自身为引用构造对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4368361/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com