#include <iostream>
using namespace std;
class A
{
public:
int x;
A(){x= 30; cout << "A constructor called " << endl;}
A(const A& obj) { cout<<"A copy constructor called " <<endl; }
};
class B
{
public:
static A sample;
B() { cout << "B constructor called " << endl; }
static A getSample() { return sample; }
};
A B::sample;
int main()
{
A one;
A two = B::getSample();
cout<<B::sample.x<<endl;
cout<<one.x<<endl;
cout<<two.x<<endl;
return 0;
}
Вышеуказанный код выводит:
A constructor called
A constructor called
A copy constructor called
30
30
-1032819680
Почему не копирует значение копии конструктора x в B::getSample()
. B::getSample()=30
словами, в то время как B::getSample()=30
, почему two.x
является -1032xxxxxx
?
Поведение правильное, копии создаются как они должны быть... но:
Если вы хотите, чтобы для параметра two.x
было 30
, вам нужно скопировать значение x
внутри вашего конструктора копий... что не так в вашем коде. Вы просто печатаете A copy constructor called
но ваш конструктор копий не имеет никакого эффекта.
Просто измените его на
A(const A& obj)
{
cout<<"A copy constructor called " <<endl;
x = obj.x; // added!
}
Затем программа отображает:
A constructor called
A constructor called
A copy constructor called
30
30
30
Вы определили свой собственный конструктор копирования, который не копирует значение x
. Поэтому он остается неинициализированным.
Имейте в виду, что Compiler создаст конструктор копии по умолчанию, если вы его не определите. Это делает мелкую копию, которая копирует каждый член класса индивидуально, используя стандартный оператор присваивания ('=').
x=obj.x;
Поскольку это именно то, что вы бы делали в любом случае, на самом деле нет причин переопределять.
Это хорошо работает, если у вас есть простой класс без динамически выделенной памяти (или указателей). Однако, если вы хотите скопировать указатель (указав на кусок данных), мелкая копия не работает. Это связано с тем, что оператор присваивания просто копирует адрес указателя и не выделяет какую-либо память или копирует содержимое, на которое указывает.
два инициализируются с использованием созданного вами конструктора копирования. И в этом определении вы не присвоили значение x. Вот почему он печатает мусор.