类只是将成员函数和成员变量放到一起吗?肯定不是的,本次主要讨论构造函数和析构函数
构造函数
Different from struct in C, a constructor will be invoked when creating an object of a class.
- struct in C: allocate memory
- class in C++: allocate memory & invoke a constructor 调用构造函数
构造函数的作用:就是对对象的数据进行初始化。
But … No constructor is defined explicitly in previous examples. The compiler will generate one with empty body
class Student
{
private:
// ...
public:
// 构造函数 1
Student()
{
name[0] = 0;
born = 0;
male = false;
}
// 构造函数2
Student(const char * initName, int initBorn, bool isMale)
{
setName(initName);
born = initBorn;
male = isMale;
}
// The members can also be initialized as follows
// born 初始化为0,male初始化为true
Student(const char * initName): born(0), male(true)
{
setName(initName);
}
};
构造函数特点:
- The same name with the class. 要跟类名完全一样
- Have no return value . 没有返回值
构造函数可有多个,只要参数不同就可以。
#include <iostream>
#include <cstring>
using namespace std;
class Student
{
private:
char name[4];
int born;
bool male;
public:
Student()
{
name[0] = 0;
born = 0;
male = false;
cout << "Constructor: Person()" << endl;
}
Student(const char *initName) : born(0), male(true)
{
setName(initName);
cout << "Constructor: Person(const char, int , bool)" << endl;
}
Student(const char *initName, int initBorn, bool isMale)
{
setName(initName);
born = initBorn;
male = isMale;
cout << "Constructor: Person(const char, int , bool)" << endl;
}
void setName(const char *s)
{
strncpy(name, s, sizeof(name));
}
void setBorn(int b)
{
born = b;
}
// the declarations, the definitions are out of the class
void setGender(bool isMale);
void printInfo();
};
void Student::setGender(bool isMale)
{
male = isMale;
}
void Student::printInfo()
{
std::cout << "Name: " << name << std::endl;
std::cout << "Born in " << born << std::endl;
std::cout << "Gender: " << (male ? "Male" : "Female") << std::endl;
}
int main()
{
Student yu;
yu.printInfo();
yu.setName("Yu");
yu.setBorn(2000);
yu.setGender(true);
yu.printInfo();
Student li("li");
li.printInfo();
Student xue = Student("XueQikun", 1962, true);
//a question: what will happen since "XueQikun" has 4+ characters?
xue.printInfo();
Student *zhou = new Student("Zhou", 1991, false);
zhou->printInfo();
delete zhou;
return 0;
}
Destructors 析构函数
- The destructor will be invoked when the object is destroyed. 对象被销毁的时候,被调用,
- Be formed from the class name preceded by a tilde (~) . 析构函数之前,类名之前加上~
Have no return value, no parameters . 析构函数不能重载,只能有一个,且没有参数和返回值 ```cpp class Student { // … public: Student() {
name = new char[1024]{0}; born = 0; male = false; cout << "Constructor: Person()" << endl;
}
// 析构函数 ~Student() {
delete [] name; // 释放内存,还有一些关闭文件,断掉网络等操作
} };
```cpp
#include <iostream>
#include <cstring>
using namespace std;
class Student
{
private:
char *name;
int born;
bool male;
public:
Student()
{
name = new char[1024]{0};
born = 0;
male = false;
cout << "Constructor: Person()" << endl;
}
Student(const char *initName, int initBorn, bool isMale)
{
name = new char[1024];
setName(initName);
born = initBorn;
male = isMale;
cout << "Constructor: Person(const char, int , bool)" << endl;
}
// 析构函数
~Student()
{
cout << "To destroy object: " << name << endl;
delete[] name;
}
void setName(const char *s)
{
strncpy(name, s, 1024);
}
void setBorn(int b)
{
born = b;
}
// the declarations, the definitions are out of the class
void setGender(bool isMale);
void printInfo();
};
void Student::setGender(bool isMale)
{
male = isMale;
}
void Student::printInfo()
{
std::cout << "Name: " << name << std::endl;
std::cout << "Born in " << born << std::endl;
std::cout << "Gender: " << (male ? "Male" : "Female") << std::endl;
}
int main()
{
{
Student yu;
yu.printInfo();
yu.setName("Yu");
yu.setBorn(2000);
yu.setGender(true);
yu.printInfo();
}
Student xue = Student("XueQikun", 1962, true);
xue.printInfo();
Student *zhou = new Student("Zhou", 1991, false);
zhou->printInfo();
delete zhou;
return 0;
}
当对象在其作用域结束之后,会调用析构函数进行销毁。这也是63行加入{}
的演示原因。
zhou是动态申请的,如果没有delete zhou;
,不会调用析构函数
#include <iostream>
#include <cstring>
using namespace std;
class Student
{
private:
char *name;
int born;
bool male;
public:
Student()
{
name = new char[1024]{0};
born = 0;
male = false;
cout << "Constructor: Person()" << endl;
}
Student(const char *initName, int initBorn, bool isMale)
{
name = new char[1024];
setName(initName);
born = initBorn;
male = isMale;
cout << "Constructor: Person(const char, int , bool)" << endl;
}
~Student()
{
cout << "To destroy object: " << name << endl;
delete[] name;
}
void setName(const char *s)
{
strncpy(name, s, 1024);
}
void setBorn(int b)
{
born = b;
}
// the declarations, the definitions are out of the class
void setGender(bool isMale);
void printInfo();
};
void Student::setGender(bool isMale)
{
male = isMale;
}
void Student::printInfo()
{
std::cout << "Name: " << name << std::endl;
std::cout << "Born in " << born << std::endl;
std::cout << "Gender: " << (male ? "Male" : "Female") << std::endl;
}
int main()
{
Student *class1 = new Student[3]{
{"Tom", 2000, true},
{"Bob", 2001, true},
{"Amy", 2002, false},
};
class1[1].printInfo();
delete class1;
// delete []class1;
return 0;
}
What is the difference between the following two lines?
delete class1;
delete []class1;
delete class1;
:可以释放掉数组的空间,但是只会调用第一个对象Tom
的析构函数,第二个Bob
和第三个对象Amy
的析构不会被调用delete []class1;
:不仅会释放内存,还会将class数组的三个对象的析构函数都会调用。
所以,当new一个数组时,在delete时要加上[]
。