Скопируйте конструктор и оператор = в C ++ - PullRequest
1 голос
/ 21 сентября 2011

У меня вопрос по поводу следующего кода:

допустим, у меня есть класс P, в котором есть конструктор копирования, и обычный конструктор получает одно строковое значение.

У меня есть следующеекод:

P doSomething(){
   P p("myValue");
   return p;
}

int main(){
    P m=doSomething();
    return 1;
}
  1. почему конструктор копирования не вызывается при return p функции doSomething()?
  2. при вызове P m=doSomething() - предполагается ли вызватьконструктор копирования или оператор =?
  3. в случае, если это оператор =, в чем разница этого кода и следующего:

    P new_val=("newVal");
    p m=new_val;
    

(я знаю, что здесь вызов для конструктора копирования)

Спасибо, Мэри

Ответы [ 3 ]

2 голосов
/ 21 сентября 2011
  • почему конструктор копирования не вызывается при возврате p функции doSomething ()?

Стандарт разрешает исключение этой копии.Google для [N] RVO.На некоторых компиляторах это происходит только при оптимизации, на других это является частью соглашений о вызовах и, таким образом, происходит всегда.

  • вызов P m = doSomething () - предполагает ли он вызвать конструктор копирования илиоператор =?

T t = x; является "синтаксическим сахаром" (в том смысле, что T(x) происходит неявно) для T t(T(x)) и, следовательно, имеет - несмотря на = -ничего общего с operator=.Обратите внимание, что здесь также может быть исключено дополнительное временное значение, поэтому не вызывается копия ctor.

  • в случае, если это оператор =, в чем разница этого кода и следующего:

Этот код не имеет смысла, что вы на самом деле имели в виду?

P new=("newVal");
p m=new;
0 голосов
/ 21 сентября 2011

Я сделал небольшой пример для демонстрации.

void print(char* text, int ident)
{
    for(int i = 0 ; i < ident ; i++)
    {
        printf("   ");
    } // end for

    fprintf(stdout, text);
    fprintf(stdout, "\n");
    fflush(stdout);
}

class P
{
public:
    char* _str;

    P (P& arg)
    {
        print("copy constructor", 2);
        arg._str = this->_str;
    }

    P (char* str)
    {
        print("constructor", 2);
        _str = str;
    }
};

P doSomething(){
    print("do something - function", 1);
    P p("myValue");
    print("before return p", 1);
    return p;
}

int main(int argc, char* argv[])
{
    print("start", 0);
    P m=doSomething();
    print("stop - call return", 0);
    return 1;
}

это возвращает

start
   do something - function
      constructor
   before return p
      copy constructor
stop - call return

, поэтому конструктор копирования будет вызываться

0 голосов
/ 21 сентября 2011

1) почему конструктор копирования не вызывается при "return p" функции doSomething ()?

следует - попробуйте распечатать что-нибудь на консоли в копирующем устройстве, чтобы увидеть, действительно ли оно работает.

2) вызов P m = doSomething () - предполагается ли вызвать конструктор копирования или оператор =?

должен вызвать оператора =. снова используйте отладочное сообщение print из метода для проверки

3) в случае, если это оператор =, в чем разница этого кода и следующего: P new = ("newVal"); р м = новый; (я знаю, что здесь вызов для конструктора копирования)

Вы что-то упустили из фрагмента кода? я думаю, что это не скомпилируется

...