构造对象本身作为参考? [英] Construct object with itself as reference?

查看:191
本文介绍了构造对象本身作为参考?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I just realised that this program compiles and runs (gcc version 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中)参数在调用方法/构造函数之前被评估,所以我怀疑这种情况必须由语言规范中的一些特殊情况覆盖。

I wonder why on earth this even compiles. I assume that (just as in Java) arguments are evaluated before the method / constructor is called, so I suspect that this case must be covered by some "special case" in the language specification?

问题:


  1. 有人可以解释这个问题/ li>
  2. 允许这样做的理由是什么?

  3. 是标准C ++还是gcc特定?






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

编辑2:即使使用 -Wall -pedantic 编译器不会抱怨测试a(a);

EDIT 2: Even with -Wall and -pedantic the compiler doesn't complain about Test a(a);.

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

EDIT 3: If I add a method

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



我甚至可以测试a ));

I can even do Test a(method(a)); without any warnings.

推荐答案

允许的原因是因为规则例如,标识符范围在标识符之后立即开始。在

The reason this "is allowed" is because the rules say an identifiers scope starts immediately after the identifier. In the case

int i = i;

RHS i是之后LHS i所以i在范围。这并不总是坏的:

the RHS i is "after" the LHS i so i is in scope. This is not always bad:

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

,因为变量可以被寻址而不使用其值。在OP的复制构造函数的情况下,不容易给出错误,因为绑定变量的引用不需要变量初始化:它等效于取变量的地址。合法的构造函数可以是:

because a variable can be addressed without its value being used. In the case of the OP's copy constructor no error can be given easily, since binding a reference to a variable does not require the variable to be initialised: it is equivalent to taking the address of a variable. A legitimate constructor could be:

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

你看到的参数只是被解决,它的值不使用。在这种情况下,自引用实际上可能有意义:列表的尾部由自引用给出。事实上,如果将next的类型更改为引用,则没有什么选择,因为您不能像指针一样容易地使用NULL。

where you see the argument is merely addressed, its value isn't used. In this case a self-reference could actually make sense: the tail of a list is given by a self-reference. Indeed, if you change the type of "next" to a reference, there's little choice since you can't easily use NULL as you might for a pointer.

像往常一样,问题是倒退。问题不是为什么变量的初始化可以引用自身,问题是为什么它不能向前推理。 [在Felix,这是可能的]。特别是,对于类型而不是变量,转发引用的能力的缺乏被极大地打破,因为它阻止递归类型被定义而不是使用不完全类型,这在C中是足够的,但不是在C ++中,由于存在模板。

As usual, the question is backwards. The question is not why an initialisation of a variable can refer to itself, the question is why it can't refer forward. [In Felix, this is possible]. In particular, for types as opposed to variables, the lack of ability to forward reference is extremely broken, since it prevents recursive types being defined other than by using incomplete types, which is enough in C, but not in C++ due to the existence of templates.

这篇关于构造对象本身作为参考?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆