#c #visual-c
#c #visual-c
Вопрос:
Что произойдет в случае конструктора копирования, если я использую указатель в параметре вместо ссылочной переменной? например
class MyClass
{
private: int a;
char *str;
public:...
...
MyClass(MyClass *pObj)
{
....
....
}
};
Комментарии:
1. Обычный ответ на вопрос, что произойдет, если …? вопросы — Напишите пример программы и убедитесь сами ..
2. это не конструктор копирования в традиционном смысле — конструктор копирования имеет определенную подпись,
MyClass(const MyClassamp;)
…
Ответ №1:
MyClass(MyClass *pObj)
Это не конструктор копирования, это перегруженный конструктор.
Конструктор копирования принимает ссылку на тот же тип, что и аргумент. Пример:
MyClass(MyClass amp;)
Компилятор неявно генерирует конструктор копирования для вашего класса, если вы не предоставляете свою собственную версию. Этот конструктор копирования будет вызываться, когда компилятору необходимо сгенерировать копию объекта.
Перегруженный конструктор, указанный выше, будет вызываться только при явном вызове его.
#include<iostream>
class MyClass
{
private: int a;
char *str;
public:
MyClass(){}
MyClass(MyClass *pObj)
{
std::cout<<"ninside *";
}
MyClass(MyClass amp;pObj)
{
std::cout<<"ninside amp;";
}
void doSomething(MyClass obj)
{
std::cout<<"ndoSomething";
}
};
int main()
{
MyClass ob,ob2;
MyClass obj2(amp;ob); //Explicitly invoke overloaded constructor
ob.doSomething(ob2); //Calls copy constructor to create temp copy of object
return 0;
}
Обратите внимание, что вывод:
inside *
inside amp;
doSomething
Комментарии:
1. Спасибо, я тоже попробовал это. Означает, что это не конструктор as, потому что мы явно вызываем его. Может ли возникнуть какая-либо проблема с нулевым значением, поскольку ссылка не содержит нулевого значения. и указатель имеет значение NULL. Я просто хочу это прояснить.
2. Это перегруженный конструктор. Да, указатели могут быть нулевыми, а ссылки не могут быть нулевыми, если ссылка равна НУЛЮ, программа уже плохо сформирована. И да, в случае перегруженного конструктора, который принимает аргумент указателя, вам нужно будет проверить значение NULL.
Ответ №2:
По определению, конструктор копирования — это конструктор с параметром ссылки const на тот же класс. Любое другое определение конструктора не является «конструктором копирования», поэтому оно не будет вызываться компилятором, когда вы пишете что-то вроде:
MyClass x = y;
или
MyClass x( y );
Ответ №3:
Предполагается, что конструктор копирования создает копию из объекта, а не из указателя.
Зачем передавать по ссылке, а не по значению? Потому что, если вы этого не сделаете, конструктор копирования перейдет к созданию копии аргумента, и это будет бесконечный цикл.
Комментарии:
1. Спасибо. правильно, но что произойдет, потому что я хочу такого случая, когда эта ситуация пойдет не так. Я попробовал код с помощью указателя, и он успешно скомпилирован и выполнен. Можете ли вы привести мне какой-либо пример, когда такое условие не будет выполнено.
2. Ваша идея вызвать что-то вроде MyClass(MyClass *) является конструктором копирования, недопустима, поскольку мы уже знаем это как параметризованный конструктор, поэтому программа будет нормально компилироваться, работать нормально, но перестаньте называть это конструктором копирования. Более того, вы пробовали это: MyClass *pObj = NULL; MyClass Obj(pObj); Он тоже работает??
3. это абсолютно верно.. Это показывает ошибку сегментации. Теперь я получил ответ на свой вопрос. Спасибо abhinav.
4. @user993009 многие программисты предпочитают выбирать ссылки, поскольку они быстрее и их не нужно проверять на NULL, и, очевидно, они избегают SEGFAULT. Теперь, я думаю, вы новичок, поэтому я должен сказать вам, что если вы удовлетворены, вы можете установить флажок слева и проголосовать. Это улучшит вашу репутацию.
5. Можете ли вы объяснить свои рассуждения / недооценку
references as they are faster
? Потому что это неверно.