该系列为C++初学者设计
编写不易,希望获得收藏,关注和转发的支持,谢谢。
构造函数基本概念
对类的对象进行初始化,因为这类是新定义的类,所以系统没有相关对象的定义范围,你只能通过自己来定义。
构造函数
类中的特殊函数
用于描述初始化算法
构造函数的作用
在对象被创建时使用特定的值构造对象,
将对象初始化为一个特定的初始状态。
例如:
希望在构造一个Clock类对象时,
将初试时间设为0:0:0,
就可以通过构造函数来设置。
构造函数的形式
函数名与类名相同
不能定义返回值类型,也不能有return语句
可以有形式参数,也可以没有形式参数
可以是内联函数
可以重载
可以带默认参数值
构造函数的调用时机
在对象创建时被自动调用
例如
Clock myclock(0,0,0)
默认构造函数
调用时可以不需要实参的构造函数
·参数表为空的构造函数
全部参数都有默认值的构造函数
下面两个都是默认构造函数
如在类中同时出现,将产生编译错误
Clock();
Clock(int newH=0,int newM=0,int newS=0);
隐含生成的构造函数
如果程序中未定义构造函数,编译器将自动生成
一个默认构造函数
参数列表为空,不为数据成员设置初始值;
如果类内定义了成员的初始值,则使用内类定义的初始值;
如果没有定义类内的初始值,则以默认方式初始化;
基本类型的数据默认初始化的值是不确定的。
=default"
如果程序中已定义构造函数,默认情况下编译器就不再隐含生成
默认构造函数。如果此时依然希望编译器隐含生成默认构造函数,
可以使用“=default”
例:
class Clock {
public:
Clock0 =default;//指示编译器提供默认构造函数
Clock(int newH, int newM, int newS); //构造函数
private:
int hour,minute,second;
}
构造函数 ——例题1
![2f2c60a447254a45a124c4b370aad444.png](https://i-blog.csdnimg.cn/blog_migrate/62075207a2d17aefe0097034b4dbff7f.jpeg)
![10bd42efa78c21eb63d7f25d4abe268e.png](https://i-blog.csdnimg.cn/blog_migrate/3e91c4899b9fd40d327d65bcd7d4292f.jpeg)
图2的构造函数定义它的初始化办法是用初始化列表的形式来做的。
这是一种首选的初始化方法,这样的话就可以简写在函数体中。来进行定义初始化。
![9d0342fc987593b58a9a2b090d2d5d69.png](https://i-blog.csdnimg.cn/blog_migrate/cf7c5800011af1d9df6704307cf3dd2f.jpeg)
![c3dca6a064b21b7d67423b7fd7572d6a.png](https://i-blog.csdnimg.cn/blog_migrate/673c63c990591d435db511ab335dc57c.jpeg)
一般会多编写一个隐含构造函数,以备在没有参数或者是其他一些情况中使用。
整体代码
include
using namespace std;
class Clock {//时钟类的定义
public: //外部接口,公有成员函数
Clock(int newH, int newM, int newS);//构造函数
Clock();//默认构造函数
void setTime(int newH = 0, int newM = 0, int newS = 0);
void showTime();
private: //私有数据成员
int hour, minute, second;
};
//时钟类成员函数的具体实现
Clock::Clock(): hour(0), minute(0), second (0) {}//默认构造函数
Clock::Clock(int newH, int newM, int news): hour(newH), minute(newM),second(new S)
void Clock::setTime(int newH, int newM, int newS)
hour = newH;
minute = newM;
second = news;
inline void Clock::showTime() {
cout<< hour <
//主函数
int main() {
Clock c(8, 10,0);//自动调用构造函数
Clock c2; //调用无参数的构造函数
c. showTime ();
c2.showTime ();
return 0;
委托构造函数
我们在一个类中重载多个构造函数时发现只有它们的形参表和初始化列表不同外初始化算法相同,函数体都是相同的。为了避免这种重复工作,我们使用到了委托构造函数。
例
回顾:
Clock类的两个构造函数:
Clock(int newH, int newM, int newS):
hour(newH), minute(newM), second(newS) //构造函数
Clock:Clock):hour(0),minute(0),second(0)//默认构造函数
利用委托构造函数,我们可以将其改进为。
委托构造函数
委托构造函数使用类的其他构造函数执行初始化过程
hour(newH),minute(newM),second(newS){}
Clock():Clock(0,0,0)() //很明显,在这一步,我们用无参数的构造函数调用了有参数的构造函数,而且这样的好处在于,如果将构造函数进行修改时,可以使其他构造函数协同改变。
复制构造函数
本质是用已存在对象去初始化新对象。
可以用已有对象的引用去做构造函数的参数。
编译器会在没有定义复制构造函数时定义一个隐含的复制构造函数,会实现两个成员之间对象的一一对应复制。
复制构造函数定义
复制构造函数是一种特殊的构造函数,其形参为本类的对象引用.
作用是用一个已存在的对象去初始化同类型的新对象。
class 类名(
类名(形参);//构造函数
类名(const类名对象名);//复制构造函数
//...
类名:类( const 类名&对象名)//复制构造函数的实现
{ 函数体 }
复制构造函数被调用的三种情况
定义一个对象时,以本类另一个对象作为初始值,发生复制构造,
1、如果函数的形参是类的对象,调用函数时,将使用实参对象初始
化形参对象,发生复制构造;
2、如果函数的返回值是类的对象,函数执行完成返回主调函数时,
3、将使用return语句中的对象初始化一个临时无名对象,传递给主
调函数,此时发生复制构造。
这种情况也可以通过移动构造避免不必要的复制
隐含的复制构造函数
如果程序员没有为类声明拷贝初始化构造函数,则编译器自己生成
一个隐含的复制构造函数。
这个构造函数执行的功能是:用初始值对象的每个数据成员,初始
化将要建立的对象的对应数据成员。
注意,一般来说,默认的复制构造函数在遇见类的成员中有指针情况的时候,隐含的复制构造函数只能达到浅层目标,达不到深层复制的要求。这时就需要自己编写复制构造函数。
简单的来说,隐含的复制构造函数就是原样照搬。
而自己定义的复制构造函数则是以自己需求的方式来对对象进行构造。
“=delete”
如果不希望对象被复制构造
C++98做法:将复制构造函数声明为private,并且不提供函数的实现。
C++11做法:用“=delete”指示编译器不生成默认复制构造函数。
·例:
class Point (//Point 类的定义
Point(int xx=0, int yy=0)(x=x; y =yy; //构造函数,内联
Point(const Point& p) =delete; //指示编译器不生成默认复制构造函数
int x,y; //私有数据
复制构造函数调用举例
int getY() const{
return y;
private: //私有数据
int x, y;
成员函数的实现
Point::Point(const Point & p){
X=p.x;
y = p.y;
cout << “Calling the coDY constructor" << endl;
//形参为Point类对象的函数
void funl(Point n){
cout <
//p. setX(1);
//返回值 为Point类对象的函数。
fun2(){
Point a;
return a;
//主程序
int main ()
Point a; //第一个对象A
Point b(a); //情况一,用A初始化B。第一次调用拷贝构造函数
cout << b.getX()<< endl;
fun1(b) //情况二,对象B作为fun1的实参。第二次调用拷贝构造函数,经调试发现,首先先进入复制构造函数,对形参对象进行初始化,之后再进入fun1函数。
b = fun2(); //情况三,函数的返回值是类对象,函数返回时,调用复制构造函数。
cout < b.getX()<< endl;
讲解:
之所以复制构造函数在情况三的应,Point a,不调用复制构造函数是因为这是个部分a只是个局部变量,当期和主函数产生联系也就是返回问一个point a这个值,这时才调用复制给我的函数。