在面向对象的编程中,对象是类的实例,该类具有自己的状态(变量)和行为(方法) 。
每个类都有两个与类的对象的创建和销毁有关的特殊方法:构造函数和析构函数。
C++对象生命周期:
要完成对象的生命周期,需要遵循各种步骤:
- 首先,需要一些类来定义基于类的对象。因此,在上图中创建了一个Example类。
- 构造函数构造类类型的值。它是一个成员函数,其名称与类名相同。此过程涉及初始化数据成员,并经常使用new分配免费存储。
- 可以像上面创建的那样初始化Example对象。初始化要求调用新的关键字,以便为该对象分配一些内存。
- 可以在构造函数中使用某些逻辑,这些逻辑将在初始化期间执行。
- 执行完成后,将调用析构函数。析构函数是成员函数,其目的是破坏类类型的值。它是一个成员函数,其名称以tilde(〜)字符开头。
- 在整个生命周期中,请记住以下事实:
- 构造函数可以重载。
- 在定义中使用构造函数的关联类型时,将调用该构造函数。
- 当对象超出范围时,将隐式调用析构函数。
- 构造函数和析构函数没有返回类型,并且不能使用return语句。
下面是有关C++中构造函数和析构函数工作方式的程序:
C++
// C++ program to demonstrate the
// object allocation & deallocation
#include
using namespace std;
class object {
public:
// Constructor
object()
{
// Constructor has same name
// as that of class name
cout << "The object is created"
<< "\n";
}
// Destructor
~object()
{
// Destructor has same name as
// class and is preceeded by ~ sign
cout << "The object is destructed"
<< "\n";
}
};
// Driver Code
int main()
{
// Object creation
object obj1;
return 0;
}
C++
// C++ program to illustrate the
// constructor and destructor when
// multiple objects are created
#include
using namespace std;
// obj Class
class obj {
public:
// Declare class variable to
// keep count on objects
static int obj_count;
// Constructor
obj()
{
obj_count++;
cout << "The obj - "
<< obj_count
<< " - is created"
<< "\n";
}
// Destructor
~obj()
{
cout << "The obj - "
<< obj_count
<< " - is destructed"
<< "\n";
obj_count--;
}
};
// Static members are always defined
// outside of the class
int obj::obj_count = 0;
// Driver Code
int main()
{
// Creating objects
obj obj1{};
obj obj2{};
return 0;
}
C++
// C++ program to demostrates the
// object Allocation and deallocation
// during inheritance B stands for base
// class and D stands for derived class
#include
using namespace std;
// Class B
class B {
public:
// Constructor
B(int b = 0)
: _b(b)
{
cout << "constructor of base class "
<< "created with value - "
<< _b << '\n';
}
// Destructor
~B()
{
cout << "Destructor of base class "
<< "called \n";
}
int _b;
};
// Inherit class D from class B
class D : public B {
public:
D(int d)
: _d(d)
{
// Default constructor of b
// Is called automatically
cout << "constructor of derived "
<< " class created with value - "
<< _d << '\n';
}
// Overloaded Constructor
D(int b, int d)
: B(b), _d(d)
{
cout << "constructor of derived class "
<< "created with value - "
<< _d << '\n';
}
// Destructor
~D()
{
cout << "Destructor of derived class "
<< "called \n";
}
private:
int _d;
};
// Driver Code
int main()
{
// Object of class B
B b(34);
// Objects of class D
D d2(89);
D d1(56, 78);
return 0;
}
The object is created
The object is destructed
当涉及多个对象时:
当从同一个类中创建多个对象时,对象的构造以与它们创建时相同的方式进行。但是,销毁遵循LIFO(后进先出)方法,即,首先创建的对象将最后被销毁。因为,当使用单个类时,每个新对象都独立于前一个对象,因此销毁顺序并不重要。但是,在处理继承时,此LIFO命令确实有意义。
下面是说明相同内容的程序:
C++
// C++ program to illustrate the
// constructor and destructor when
// multiple objects are created
#include
using namespace std;
// obj Class
class obj {
public:
// Declare class variable to
// keep count on objects
static int obj_count;
// Constructor
obj()
{
obj_count++;
cout << "The obj - "
<< obj_count
<< " - is created"
<< "\n";
}
// Destructor
~obj()
{
cout << "The obj - "
<< obj_count
<< " - is destructed"
<< "\n";
obj_count--;
}
};
// Static members are always defined
// outside of the class
int obj::obj_count = 0;
// Driver Code
int main()
{
// Creating objects
obj obj1{};
obj obj2{};
return 0;
}
The obj - 1 - is created
The obj - 2 - is created
The obj - 2 - is destructed
The obj - 1 - is destructed
在继承的情况下对象构造和销毁的行为:
C++中的继承遵循IS-A方法。当类B继承了类A时,我们说B IS-A 。我们说B类是派生类, A类是基类。除了状态和行为,类B还继承了类A的构造函数和析构函数。有一些规则指导构造函数和析构函数的继承。
- 派生类不能覆盖或重载基类的构造函数和析构函数。
- 首先进行基类的构建,然后进行派生类的构建。
- 派生类的破坏首先发生。
下面是说明相同内容的程序:
C++
// C++ program to demostrates the
// object Allocation and deallocation
// during inheritance B stands for base
// class and D stands for derived class
#include
using namespace std;
// Class B
class B {
public:
// Constructor
B(int b = 0)
: _b(b)
{
cout << "constructor of base class "
<< "created with value - "
<< _b << '\n';
}
// Destructor
~B()
{
cout << "Destructor of base class "
<< "called \n";
}
int _b;
};
// Inherit class D from class B
class D : public B {
public:
D(int d)
: _d(d)
{
// Default constructor of b
// Is called automatically
cout << "constructor of derived "
<< " class created with value - "
<< _d << '\n';
}
// Overloaded Constructor
D(int b, int d)
: B(b), _d(d)
{
cout << "constructor of derived class "
<< "created with value - "
<< _d << '\n';
}
// Destructor
~D()
{
cout << "Destructor of derived class "
<< "called \n";
}
private:
int _d;
};
// Driver Code
int main()
{
// Object of class B
B b(34);
// Objects of class D
D d2(89);
D d1(56, 78);
return 0;
}
constructor of base class created with value – 34
constructor of base class created with value – 0
constructor of derived class created with value – 89
constructor of base class created with value – 56
constructor of derived class created with value – 78
Destructor of derived class called
Destructor of base class called
Destructor of derived class called
Destructor of base class called
Destructor of base class called
为什么在对象销毁过程中使用LIFO方法?
由于子类继承自父类的状态和行为,因此首先完成子类的所有工作,然后仅销毁基类的对象是有意义的。假设子类从父类访问状态,但是父对象已被破坏,在这种情况下,将发生错误,因此将破坏LIFO顺序。即使使用单个类的多个对象,这也很好。