Member 12914219 Ответов: 2

Почему не вызывается конструктор копирования


в операторе strin z=x+y должен быть вызван конструктор копирования ....так как x+y возвращает строку .приведенное выше утверждение должно вызывать конструктор копирования....но оно не вызывается....я пропустил какое-то понятие о конструкторе копирования

Что я уже пробовал:

#include <iostream>
#include<string.h>

using namespace std;
class strin
{
    int len;
    char *p;
    public:
        strin(){len=0;p=NULL;}
        strin( const char *s){cout<<"cons is called\n";
            len=strlen(s);
            p=new char[len+1];
            strcpy(p,s);



        }

         strin( const strin &s)
        {
            len=s.len;
            p=new char[len+1];
            strcpy(p,s.p);
        }

        ~strin()
        {
            delete p;
            cout<<"des is called\n";


        }


    strin operator +( const strin  &obj )
    {
        strin temp;
        temp.len =obj.len+len;
        temp.p=new char[temp.len];
        strcpy(temp.p,p);
        strcat(temp.p,obj.p);
        return temp;
        cout<<"opr is called"<<"\n";
    }
    void print(void)
    {
        cout<<p<<"\n";

    }

};
int main()
{


strin x="hello";

strin y="bob";
strin z=x+y;

z.print();

}

Kornfeld Eliyahu Peter

Почему? Вы уже сконструировали обе ваши переменные!!!

0x01AA

Но как насчет возвращаемого значения для operator+ Здесь я ожидал бы вызова конструктора копирования....

Member 12914219

вот что я говорю

0x01AA

Просто протестировал его и нашел (с помощью отладчика и точки останова в Operator+ и конструкторе копирования. В моем случае он вызовет конструктор копирования.

Member 12914219

я узнал, что конструктор копирования вызывается, когда новый объект создается из существующего объекта....например, strin obj1=obj2;....утверждение strin z= x+y равно strin z=(некоторый объект)...я думаю, что следует вызвать конструктор копирования

Richard MacCutchan

неправильный.

Member 12914219

я знаю, но моя операторная функция возвращает объект ... так что strin z=(object)
должен вызвать конструктор копирования...... и еще одна вещь ..если я объявлю объект, а затем использую его ...он не добавит две строки ..есть какое-то мусорное значение.... ex
тап_п()
{
strin x="привет";

Стрин г="Вася";

Стрин з;
z=x+y;
з.печать();

}

0x01AA

Ошибаешься! В то время как оператор return fro+ существует необходимость вызвать конструктор копирования для возвращаемого значения.

0x01AA

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

Richard MacCutchan

Мой тест провалился из-за ошибки в исходном коде. Я исправился.

2 Ответов

Рейтинг:
12

0x01AA

Конструктор копирования будет вызван в ожидаемом месте, которое находится:

strin operator +( const strin  &obj )
    {
        strin temp;
        temp.len =obj.len+len;
        temp.p=new char[temp.len];
        strcpy(temp.p,p);
        strcat(temp.p,obj.p);
        return temp;             //<<<<<<Here
    }


Просто протестировано с вашим исходным кодом 1:1. Как вы проверяете, вызывается ли конструктор копирования?
[Edit0]
Пожалуйста, имейте в виду, что это конструктор копирования:
strin( const strin &s)
{
...
}

пока
strin( const char *s){...}

принимает ли конструктор char*

[Edit1]
Деструктор
Вы должны использовать delete[] p;

[Edit2]
Кроме того, конструктор копирования не так уж чист, всегда делает строку длиннее на 1 для каждой копии ;) Но я думаю, что в данный момент об этом не может быть и речи ;)


Member 12914219

я использую cout в конструкторе копирования.....но все равно его не печатная копия const называется

0x01AA

Я не вижу этого cout в вашем коде выше. Но в любом случае попробуйте сделать это с помощью отладчика, и вы увидите, что вы правы в ожиданиях, что конструктор копирования должен быть вызван.

Member 12914219

я добавил cout в copy contructer ..но это не печать

0x01AA

Опять же, попробуйте сделать это с помощью отладчика....

0x01AA

Теперь я вижу, что ты должен поместить Коута сюда:
strin( const strin &s)
{
...
}


strin( const char *s){... } это не конструктор копирования, это конструктор, который принимает char* в качестве аргумента.

Member 12914219

я пробовал ... но все равно он не вызывает конструктор копирования

Member 12914219

я разместил там только суда, но до сих пор его не печать, которая означает, конструктор копирования не вызывается

Member 12914219

класс Стрин
{
инт лен;
char *p;
общественный:
strin(){len=0;p=NULL;}
strin( const char *s){cout<<"cons называется\n";
len=strlen(s);
p=новый символ[len+1];
strcpy(p,s);



}

Стрин( const strin &s)
{
cout<<"cpy const is clled";
лен=С. лен;
p=новый символ[len+1];
и strcpy(P или S.п);
}

-Стрин()
{
удалить p;
cout<<"des называется\n";


}


оператор strin +( const strin &obj )
{
Стрин темп;
темп.лен =obj-файлы.лен+лен;
temp.p=новый символ[temp.len];
strcpy(temp.p,p);
функции strcat(темп.п параметр obj.п);
cout<<"opr называется"<< " \n";
возвратная температура;

}
печать недействительным(ничтожным)
{
cout<<p<<"\n";

}

};
тап_п()
{


strin x="привет";

Стрин г="Вася";

strin z=x+y;
з.печать();


}

0x01AA

Есть ли шанс, что вы не заметите его из-за отсутствия "\r\n"
cout<<"cpy const is clled";

CPallini

5. кстати, он не увеличивает длину строки при каждой копии.

0x01AA

Большое Вам за это спасибо.
Кстати: я все еще думаю, что он увеличивает длину при использовании конструктора копирования. Это происходит потому, что он будет принимать длину строки, которая будет скопирована, и использовать эту длину + 1 для выделения нового массива символов.
Еще раз спасибо, что показали мне мою ошибку.

Maciej Los

5ed!

0x01AA

Большое тебе спасибо Мацей

Рейтинг:
1

Jochen Arndt

strin operator +( const strin  &obj )
{
    // ...
    return temp;
    // This is never executed because the function has been left by the above statement
    cout<<"opr is called"<<"\n";
}


Rick York

Это должно вызвать предупреждение о недостижимом коде в Visual Studio с соответствующей настройкой уровня предупреждения. Я не уверен, какой именно, потому что я всегда использую уровень 4.

Jochen Arndt

Предупреждение-C4702, который требует уровня 4.
AFAIK, который не является уровнем по умолчанию (по крайней мере, для релизных сборок).

Но из кода не ясно, использует ли он VS. Другие компиляторы, такие как GNU, также требуют более высокого (не по умолчанию) уровня для выдачи предупреждения.

Я всегда использую-Wall со всеми компиляторами и типами сборки.