最近对C++的构造函数做了一个小小的总结,说是C++,其实java等面向对象高级语言对构造函数处理的本质都是一样的,只不过是有些许语法的区别罢了。
1、 为什么需要构造函数?
当我们在创建一个对象时,常常需要做一些初始化的工作,为了解决这个问题,C++的编译器大牛们专门为我们提供了构造函数来处理对象的初始化,构造函数是在我们建立对象是,自动调用的。
也可以这样理解,当我们在创建游戏角色时(创建一个对象),服务器往往会给游戏角色一些基本的属相和装备(做一些初始化工作),这个是服务器自动分配给我们的,不需要我们做什么,伴随着我们角色的创建产生的。这种默认分配可以理解为构造函数的作用。
2、定义
很简单: 类名(参数){ 函数体 }
注意:(1)函数名必须与类名相同 (2)没有返回值
3、分类
默认构造函数:
1)默认无参构造函数
当类中没有定义构造函数时,编译器默认提供一个无参构造函数,并且其函数体为空
2)默认拷贝构造函数
当类中没有定义拷贝构造函数时,编译器默认提供一个默认拷贝构造函数,简单的进行成员变量的值复制(浅拷贝)
也可以这样理解(很重要的):
没有自定义构造函数时,C++编译器会自动调动相应默认构造函数(无参和copy构函数)
有了自定义的无参或者普通参数构造函数时,C++编译器将不会提供默认的无参构造函数,但是还会提供默认copy构造函数。
有了自定义的copy构造函数时,C++编译器将不会再提供默认的copy构造函数,但是还会提供默认无参构造函数。
4、调用方式
先贴出我的Cat类:
#pragma once class Cat { private: int m_age; public: Cat(void); //无参构造函数 Cat(int age); //普通有参构造函数 Cat(Cat & cat); //copy构造函数 int getAge(); //普通成员函数(这种也可叫做获取器) void setAge(int age); //普通成员函数(这种也可叫做设置器) ~Cat(void); };
Cat.cpp
#include "Cat.h" #include <iostream> using namespace std; //无参构造函数 Cat::Cat(void) { m_age =0; cout<<"无参构造函数进行初始化"<<endl; } //普通有参构造函数 Cat::Cat(int age) { m_age = age; cout<<"普通有参构造函数进行初始化"<<endl; } //copy构造函数 Cat::Cat(Cat & cat) { m_age = cat.getAge(); cout<<"copy构造函数进行初始化"<<endl; } //普通成员函数(这种也可叫做获取器) int Cat::getAge() { return m_age; } //普通成员函数(这种也可叫做设置器) void Cat::setAge(int age) { m_age = age; } Cat::~Cat(void) { cout<<"此对象被析构了"<<endl; }
调用方式分两种:1、括号法 2、等号法
代码展示:
#include <iostream> using namespace std; #include "Cat.h" int main() { //调用无参构造函数 Cat t1; Cat t2(); Cat t3 = Cat(); //调用有参构造函数 Cat m1(22); Cat m2 = (33); Cat m3 = Cat(44); //调用copy构造函数 Cat s1; Cat n1(s1); Cat n2 = s1; Cat n3 = Cat(s1); system("pause"); }
5、深入理解copy构造函数和匿名构造函数
(1)将实体对象做实参传给函数
代码如下,大家有兴趣可以断点调试一下,就知道大体流程了。
#include <iostream> using namespace std; #include "Cat.h" void func(Cat cat) { cout<<cat.getAge()<<endl; } int main() { Cat cat1; func(cat1); //在将实参cat1初始化给形参cat时。调用形参cat的copy构造函数。 }
流程如下:
(2)将函数中的实体对象作为函数的返回值返回
代码如下:
#include <iostream> using namespace std; #include "Cat.h" Cat func() { Cat cat2(22); return cat2; //在return cat2时,C++编译器会调用cat2的拷贝构造函数,生成一个匿名对象 } int main() { Cat cat1 = func(); //如果func函数的返回值要赋给的对象还没有初始化,就将func函数产生的匿名对象变成cat1 Cat cat3; cat3 = func(); //如果func函数的返回值要赋给的对象已经初始化过,就将func函数产生的匿名对象析构,将其值赋值给cat1 }
流程如下:
最后希望能对大家有帮助,沙米才疏学浅,有什么错误请留言指正,谢谢大家。