2012-03-31 4 views
7

В этом фрагменте кода, который на самом деле называется конструктором?Какой конструктор вызывается здесь?

Vector v = getVector(); 

Vector имеет конструктор копирования, конструктор по умолчанию и оператор присваивания:

class Vector { 
public: 
    ... 
    Vector(); 
    Vector(const Vector& other); 
    Vector& operator=(const Vector& other); 
}; 

getVector возвращается по значению.

Vector getVector(); 

В коде используется стандарт C++ 03.

Фрагмент кода выглядит так, как будто он должен вызвать конструктор по умолчанию, а затем оператор присваивания, но я подозреваю, что это объявление является другой формой использования конструктора копирования. Что правильно?

ответ

8

Когда в инициализации появляется =, он вызывает конструктор копирования. Общий вид не совсем то же самое, что и вызов конструктора копирования. В заявлении T a = expr; происходит то, что если expr имеет тип T, вызывается конструктор копирования. Если expr не относится к типу T, тогда сначала выполняется неявное преобразование, если возможно, тогда конструктор копирования вызывается с ним в качестве аргумента. Если неявное преобразование невозможно, то код плохо сформирован.

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

+0

Одно правило, стоящее ничто, заключается в том, что конструктор копирования должен быть доступен (например, общедоступный), даже если сама по себе сама конструкция копии исключается. Таким образом, возможно, что конструктор копирования будет закрыт, код не будет компилироваться и сделать его общедоступным, он будет компилироваться, но конструктор копирования не будет вызван. – 6502

+0

«тот же физический объект, который хранится в v» - скорее, объект, созданный внутри функции, представляет собой тот же физический объект, что и 'v'. Обычно я говорю, что либо 'v' - это имя объекта, либо' v' - этот объект, но не «объект хранится в' v' ". Обычная реализация этой копии - это то, что вызывающий элемент getVector передает указатель в качестве дополнительного скрытого параметра, а 'getVector' создает возвращаемое значение по этому адресу. В этом случае стандарт позволяет вызывающему коду передавать '& v' в качестве скрытого параметра. –

0

Конструктор копирования на самом деле получает опущены в этом случай (проверка this) и просто конструктор по умолчанию заканчивает тем, что называется

EDIT:

конструктор только иногда опущены, а в ответ Беньямина. По какой-то причине я читал это, когда вы вызываете конструктор напрямую.

2

Предполагая, что вы не сделали что-то патологическое вне кода вы показываете, ваша декларация является копией инициализации, а вторая часть этого правила относится:

13.3.1.3 Initialization by constructor [over.match.ctor] 

1 When objects of class type are direct-initialized (8.5), or copy-initialized from an 
    expression of the same or a derived class type (8.5), overload resolution selects the 
    constructor. For direct-initialization, the candidate functions are all the constructors 
    of the class of the object being initialized. For copy-initialization, the candidate 
    functions are all the converting constructors (12.3.1) of that class. The argument 
    list is the expression-list within the parentheses of the initializer. 

Для простого теста см пост Эли Бендерский, вот: http://eli.thegreenplace.net/2003/07/23/variable-initialization-in-c/

1

Всегда помните правило:
Всякий раз, когда объект создается и дал какое-то значение в том же одном операторе то никогда задание.

Чтобы добавить Далее,

Случай 1:

Vector v1; 
Vector v(v1); 

Случай 2:

Vector v = getVector(); 

В приведенных выше двух форматов Случай 1 является Прямая инициализация, а Корпус 2 известен как Инициализация копирования.

Как работает инициализация копирования?
Копировать инициализацию создает неявную последовательность преобразований: она пытается преобразовать возвращаемое значение getVector() объекту типа Vector. Затем он может скопировать созданный объект в инициализированный объект, поэтому ему нужен доступный конструктор копирования.

Смежные вопросы