Почему это объявление объекта класса работает? - PullRequest
0 голосов
/ 04 октября 2018

Предположим, у меня есть класс

class Test{
  public:
    int x;
    Test(const Test& obj){x=obj.x;}
};

Почему

Test object_name(Test random_name);

работает и не нуждается в другом объекте в качестве параметра ?.Что-то вроде Test random_name(Test another_random(...)), что делает его бесконечным способом объявления объекта?

Ответы [ 3 ]

0 голосов
/ 04 октября 2018

Замените Test на PoD, подобное int, и вы увидите, что происходит

Test object_name(Test random_name); //1

int object_name(int random_name); //2

. Вы можете видеть, что второе утверждение является объявлением функции, которое принимает int в качестве аргумента ивозвращает int.

Это связано с хорошо известным правилом CPP, связанным с разрешением неоднозначности.
Из рабочего проекта CPP (N4713):

9.8 Разрешение неоднозначности [stmt.ambig]

1 В грамматике существует неоднозначность, касающаяся выражений-выражений и объявлений: Выражение-выражение с явным преобразованием типа в виде функции в видекрайнее левое подвыражение может быть неотличимо от объявления, где первый декларатор начинается с (. . В этих случаях оператором является объявление .

2 [Примечание: Еслиоператор не может быть синтаксически объявлением, здесь нет двусмысленности, поэтому это правило не применяется . Может потребоваться изучить весь оператор, чтобы определить,дело.

0 голосов
/ 04 октября 2018

Вот переработанная версия, которая должна помочь объяснить, что происходит.Я добавил еще один конструктор, чтобы проиллюстрировать, что происходит.

#include <iostream>

using namespace std;

class Test{
  public:
    int x = 27;
    Test(const int y) : x(y) { cout << "ctor-1" << endl; }
    ~Test() {}
    Test(const Test& obj) : x(obj.x) { cout << "ctor-2" << endl; }
    operator int() const { return x; }
};

int main()
{
    cout << "Creating function declaration" << endl;
    Test object_name(Test random_name);

    // This works fine
    cout << "Creating alpha" << endl;
    Test alpha(4);
    cout << "Calling `object_name`" << endl;
    cout << object_name(alpha) << endl;

    // This fails because object_name is a function.
    // cout << object_name.x << endl;
    return 0;
}

Test object_name(Test random_name)
{
    cout << "Creating another Test within `object_name`." << endl;
    return Test(random_name.x + 13);
}

Здесь мы видим, что первый конструктор вызывается дважды: один раз для alpha и снова внутри object_name.Второй конструктор вызывается, когда мы вызываем object_name, который принимает параметр, переданный по значению.

Output

Creating function declaration
Creating alpha
ctor-1
Calling `object_name`
ctor-2
Creating another Test within `object_name`.
ctor-1
17
0 голосов
/ 04 октября 2018

Эта строка:

Test object_name(Test random_name);

объявляет функцию с именем object_name, которая принимает Test в качестве параметра и возвращает Test.Он не объявляет объект.Совершенно законно объявлять такую ​​функцию внутри другой функции, просто неявно extern.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...