使用数据成员与堆
编写自己的 构造函数、析构函数、拷贝构造函数 的原因都是类的数据成员使用了
堆 (Heap) 的内存,也可以说是使用了指针。
1.构造函数
Critter(const string& name = "", int age = 0);
2.析构函数
~Critter();
3.拷贝构造函数
Critter(const Critter& c)p;
为什么要使用拷贝构造函数? –>
如果只使用默认拷贝构造函数,对象的自动复制将导致新的对象指向堆中的一个字符串,
因为新对象的指针仅仅获得存储在原始对象的指针中地址的一个副本。俗称 “浅拷贝” :即
副本对象的指针数据成员与原始对象的指针数据成员指向同一内存块。
而编写自己的拷贝构造函数实现 “深拷贝”
Critter::Critter(const Critter& c)
{
cout << "Copy Constructor called\n"; // console log
m_pName = new string(*(c.m_pName)); // locate a new memory for new object
m_Age = c.m_Age; // assign a normal data
}
4.赋值运算符的重载
同样的,防止赋值的“浅拷贝”!
代码实现
// Heap data member
// Demonstrates an object with a dynamically allocated data member
#include <iostream>
#include <string>
using namespace std;
class Critter
{
public:
Critter(const string& name = "", int age = 0);
~Critter(); // destructor prototype
Critter(const Critter& c); // copy constructor prototype
Critter& operator=(const Critter& c); // overloaded assignment op
void Greet() const;
private:
string* m_pName;
int m_Age;
};
Critter::Critter(const string& name, int age)
{
cout << "Constructor called\n";
m_pName = new string(name);
m_Age = age;
}
Critter::~Critter()
{
cout << "Destructor called\n";
delete m_pName;
}
Critter::Critter(const Critter& c)
{
cout << "Copy Constructor called\n";
m_pName = new string(*(c.m_pName));
m_Age = c.m_Age;
}
Critter& Critter::operator=(const Critter& c)
{
cout << "Overloaded Assignment Operator Called\n";
if (this != &c)
{
delete m_pName;
m_pName = new string(*(c.m_pName));
m_Age = c.m_Age;
}
return *this;
}
void Critter::Greet() const
{
cout << "I'm " << *m_pName << " and I'm " << m_Age << " years old. ";
cout << "&m_pName: " << &m_pName << endl;
}
void testDestructor();
void testCopyConstructor(Critter aCopy);
void testAssignmentOp();
int main()
{
testDestructor();
cout << endl;
Critter crit("Poochie", 5);
crit.Greet();
testCopyConstructor(crit);
crit.Greet();
cout << endl;
testAssignmentOp();
return 0;
}
void testDestructor()
{
Critter toDestory("Rover", 3);
toDestory.Greet();
}
void testCopyConstructor(Critter aCopy)
{
aCopy.Greet();
}
void testAssignmentOp()
{
Critter crit1("crit1", 7);
Critter crit2("crit2", 9);
crit1 = crit2;
crit1.Greet();
crit2.Greet();
cout << endl;
Critter crit3("crit3", 11);
crit3 = crit3;
crit3.Greet();
}