构造函数
- 没有返回类型(同时也不可写void),函数名称 与 类名相同,可以发生重载,可以有参数
- 构造函数的功能是对对象进行初始化,因此在构造函数中只能对数据成员做初始化
- 构造函数可以在类内定义也可以在类外定义
- 在程序运行时,当新的对象被建立,该对象所属的类的构造函数自动被调用,在该对象生存期中也只调用这一次。
- 如果程序中不声明构造函数,那么系统会默认生成一个构造函数
cow.h
#include <iostream>
class Cow
{
char name[20];
char * hobby;
double weight;
public:
Cow(); //无参构造函数
Cow(const char * nm, const char * ho, double wt); 带参构造函数
Cow(const Cow & c); //拷贝构造函数
~Cow(); //析构函数
Cow & operator=(const Cow & c); //调用构造函数需要对'='进行重载
void ShowCow() const;
};
cow.cpp
#include <iostream>
#include "cow.h"
Cow::Cow() //初始化
{
name[0] = '\0';
hobby = nullptr;
weight = 0.0;
}
Cow::Cow(const char * nm, const char * ho, double wt)
{
strcpy(name, nm);
int len = strlen(ho);
hobby = new char[len + 1];
strcpy(hobby, ho);
weight = wt;
std::cout << "<" << name << " custom create >\n";
}
Cow::Cow(const Cow & c) //用一个已有的对象类初始化新的同一个类的对象。
{
strcpy(name, c.name);
int len = strlen(c.hobby);
hobby = new char[len + 1];
strcpy(hobby, c.hobby);
weight = c.weight;
}
Cow::~Cow() //析构函数当对象的生命期结束时,对内存进行清理工作
{
std::cout << "< " << name << " delete >\n";
delete [] hobby;
}
Cow & Cow::operator=(const Cow & c)
{
std::cout << "< " << " = operator be call >\n";
if (this == &c) // //用this指针来与自身进行比较
return *this;
strcpy(name, c.name);
int len = strlen(c.hobby);
hobby = new char[len + 1];
strcpy(hobby, c.hobby);
weight = c.weight;
return *this;
}
void Cow::ShowCow() const
{
using std::cout;
using std::endl;
cout << "name: " << name
<< ", hobby: " << hobby
<< ", weight: " << weight << endl;
}
main.cpp
#include <iostream>
int main()
{
using namespace std;
{
Cow n1("xxx", "sss", 45.6); //调用带参构造函数
Cow n2("qqq", "www", 41.2); //调用带参构造函数
n1.ShowCow();
n2.ShowCow();
Cow n3 = n1;
n3.ShowCow();
Cow n4 = Cow(); //调用无参构造函数
n4 = n2;
n4.ShowCow();
}
cout << "Done.\n";
return 0;
}
析构函数
- 析构函数函数的名字特别,是类名加“~”字符
- 析构函数没有参数,不能指定返回值类型
- 一个类中只能定义一个析构函数,所以析构函数不能重载
- 在对象生存期结束时,系统自动调用析构函数
- 如果没有定义析构函数,系统会默认生成一个析构函数
构造函数调用规则
默认情况下,c++编译器至少为我们写的类增加3个函数
1.默认构造函数无参,函数体为空
2.默认析构函数无参,函数体为空
3.默认拷贝构造函数,对类中非静态成员属性简单值拷贝
如果用户定义拷贝构造函数,c++不会再提供任何默认构造函数
如果用户定义了普通构造(非拷贝),c++不再提供默认无参构造,但是会提供默认拷贝构造
再提一下new 运算符 和 delete运算符
代码中有用到new, delete,提一嘴
-
new
C++中解决动态内存分配的方案是把创建一个对象所需要的操作都结合在一个称为new的运算符里。当用new创建一个对象时,它就在堆里为对象分配内存并调用构造函数完成初始化。
hobby = new char[len + 1];
-
delete
delete表达式先调用析构函数,然后释放内存。正如new表达式返回一个指向对象的指针一样,delete需要一个对象的地址。
delete只适用于由new创建的对象
Cow::~Cow()
{
delete [] hobby;
}
- 注意:使用new和delete采用相同形式
如果在new表达式中使用[],必须在相应的delete表达式中也使用[]
如果在new表达式中不使用[],则在相应的delete表达式中也不要使用[]