C++之类和对象的使用(一)

  对象的初始化

在声明类时直接对数据成员初始化是错误的!下面的例子时错误的!!

class Time{
hour =0;
minitu=0;
sec=0;
}  //因为类并不是一个实体,而是一种抽象类型,并不占存储空间,显然无处容纳数据;

如果一个类中的所有成员都是public类型,则可以在定义对象的时候对数据成员初始化。

class Time{
public:
hour;
minitu;
sec;
};

Time t1={13,12,40};//类似于结构体初始化成员,但仅限于public数据成员

用构造函数实现数据成员的初始化

C++提供了构造函数来处理对象的初始化。构造函数是一种特殊的成员函数,与其他成员函数不同,不需要用户来调用它,而是在建立对象时自动执行;构造函数的名字必须与类名相同,不具有任何类型,不具有返回值;

1)在类内定义构造函数

class Time{
public:
 Time(){
         hour =0;
         minitu=0;
         sec=0;
         }
} 

Time t1={13,12,40};

2)在类内声明,在类外定义

class Time{
public:
 Time();//声明构造函数
} 

Time::time()
{
hour=0;
minute=0;
sec=0;
}

构造函数的使用,有以下说明:

1)什么时候调用构造函数?在建立对象的时候会自动调用构造函数。在建立对象时为该对象分配存储单元,此时执行构造函数,就把指定的初值送到有关数据成员的存储单元。每建立一个对象,就调用一次构造函数。

2)构造函数没有返回值,也没有类型,作用只是对对象进行初始化。

3)构造函数不需要用户调用,也不被用户调用。

t1.Time();//错误

4)可以用一个类对象初始化另一个对象。

Time t1; //建立对象t1,同时调用构造函数t1.Time()
Time t2=t1;//建立对象t2,并调用一个t1初始化t2

此时,把对象t1的各数据成员的值复制到t2相应的各成员,而不调用构造函数t2.Time()

5)在构造函数的函数体中不仅可以对数据成员赋初值,也可以包含其他语句,如cout语句,但是一般不提倡。

6)如果用户没有定义,则系统会自动生成一个构造函数,只是这个构造函数的函数体时空的,也没有参数,不执行初始化操作;

 带参数的构造函数

有时用户希望对不同的对象赋予不同的初值,这就需要考虑带参数的构造函数了。在调用不同对象的构造函数时,从外面将不同的数据传递给构造函数,以实现不同的初始化。构造函数首部的一般形式为:

构造函数名(形参1,形参2,......)

实参必须在定义对象时给出,定义对象的一般形式为:

类名  对象名(实参1,实参2,......)

#include<iostream>
using namespace std;

class Box
{public:
    Box(int,int,int);//声明构造函数
    int volume();
 private:
     int height;
     int width;
     int length;
};
Box::Box(int h,int w,int len) //类外定义 构造函数
{
    height=h;
    width=w;
    length=len;
}

int Box::volume()
{
    return(height*width*length);
}

int mian()
{
    Box box1(14,12,48);//建立对象box1,给出实参
    cout<<"the box2 is:"<<box2.volume()<<endl;
        return 0;
 } 

1)带参数的构造函数中的形参,其对应的实参是建立对象时给定的。即建立对象的同时指定数据成员的初值。

2)定义不同对象时用的实参是不同的,它们反应不同对象的属性。用这种方法可以方便地实现对不同的对象进行不同的初始化。

用参数初始化表对数据成员初始化

定义构造函数可以用如下形式:

类名::构造函数名([参数表])[:成员初始化表]{ [构造函数体]}//方括号内为可选项(可有可无)

Box::Box(int h,int w,int len):height(h),width(w),length(len){}

  构造函数的重载

一个类中可以定义多个构造函数,以便为对象提供不同的初始化的方法。这些构造函数有相同的名字,而参数的个数或参数的类型不同,称为构造函数的重载。

#include<iostream>
using namespace std;

class Box
{public:
    Box();
    Box(int h,int w,int len):height(h),width(w),length(len){}
    int volume();
 private:
     int height;
     int width;
     int length;
};
Box::Box()
{
    height=10;
    width =10;
    length=10;
}

int Box::volume(){
    return(height*width*length);
}

int main()
{
    Box box1;//建立对象box1,不指定实参
    cout<<"the box1 is:"<<box1.volume()<<endl;
    Box box2(14,12,48);
    cout<<"the box2 is:"<<box2.volume()<<endl;
    return 0;
 } 
///////////////////////////
Box::Box(int h)
Box::Box(int h,int w)

1)在建立对象时不必给出实参的构造函数,称为默认构造函数。显然,无参构造函数属于默认构造函数;一个类只能有一个默认构造函数。

2)在建立对象时选用的是无参构造函数,应注意正确书写定义对象的语句。构造函数是不能被用户显式调用的。

3)尽管在一个类中可以包含多个构造函数,但是对于每一个对象来说,建立对象时只执行其中一个构造函数。

使用默认参数的构造函数

构造函数中参数的值既可以通过实参传递,也可以指定位某些默认值,即如果用户不指定实参值,编译系统就使形参取默认值。

#include<iostream>
using namespace std;

class Box
{public:
    Box(int h=10,int w=10,int len=10);
    int volume();
 private:
     int height;
     int width;
     int length;
};
Box::Box(int h,int w,int len)
{
    height=h;
    width=w;
    length=len;
}

int Box::volume(){
    return(height*width*length);
}

int mian()
{
    Box box1;
    cout<<"the box1 is:"<<box1.volume()<<endl;
    Box box2(14,12);
    cout<<"the box2 is:"<<box2.volume()<<endl;
    Box box3(14,12,48);
    cout<<"the box3 is:"<<box3.volume()<<endl;
    return 0;
 } 

说明:

1)应该在什么地方指定构造函数的默认参数?应在声明构造函数时指定默认值,而不是只能在定义构造函数时指定默认值。因为声明是放在头文件中,它是类的对外接口。

2)第五行等价于

 Box(int=10,int=10,int=10);//省去形参名

3)如果构造函数的全部参数都指定了默认值,则在定义对象时可以给一个或几个实参,也可以不给出实参。可以不用参数而调用的构造函数,一个类只能有一个。下面是错误的!!

    Box();//声明一个无参的构造函数
    Box(int=10,int=10,int=10);//声明一个全部参数都指定了默认值的构造函数

4)在一个类中定义了全部是默认参数的构造函数后,不能再定义重载构造函数。

Box(int=10,int=10,int=10); 
Box();
Box(int,int);
若有以下定义语句:
Box box1;//是调用上面第一个还是第二个构造函数??
Box box2(12,89);//是调用上面第一个还是第三个构造函数??

若有以下情况:

Box();
Box(int=10,int=10,int =10); 
Box(int,int);
若有以下定义语句:
Box box1;//正确,调用第一个
Box box2(12);//正确,调用第二个
Box box3(12,89);//错误,出现歧义

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏云霄雨霁

字符串排序----三向字符串快速排序

2050
来自专栏前端儿

前缀式计算

输入有多组测试数据,每组测试数据占一行,任意两个操作符之间,任意两个操作数之间,操作数与操作符之间都有一个空格。输入的两个操作数可能是小数,数据保证输入的数都是...

1511
来自专栏数据结构与算法

1696:逆波兰表达式

1696:逆波兰表达式 查看 提交 统计 提问 总时间限制: 1000ms 内存限制: 65536kB描述逆波兰表达式是一种把运算符前置的算术表达式,例如普通的...

3707
来自专栏机器学习算法与Python学习

Python: numpy总结(2)

11、xrange 例子: for i in xrange(3): print i test=[1,2,3,4] print test...

3315
来自专栏C/C++基础

常见排序算法分类

  此篇博客不讨论排序算法的思想,时间复杂度,空间复杂度,实现代码。只介绍常见排序算法有哪些,并按照什么进行分类。   排序算法分为两大类: 比较类...

1292
来自专栏magicsoar

Effective Modern C++翻译(3)-条款2:明白auto类型推导

条款2 明白auto类型推导 如果你已经读完了条款1中有关模板类型推导的内容,那么你几乎已经知道了所有关于auto类型推导的事情,因为除了一个古怪的例外,aut...

19310
来自专栏数据结构与算法

U9249 【模板】BSGS

题目描述 给定a,b,p,求最小的非负整数x 满足a^x≡b(mod p) 若无解 请输出“orz” 输入输出格式 输入格式: 三个整数,分别为a,b,p 输出...

3497
来自专栏武培轩的专栏

Leetcode#561. Array Partition I(数组拆分 I)

给定长度为 2n 的数组, 你的任务是将这些数分成 n 对, 例如 (a1, b1), (a2, b2), ..., (an, bn) ,使得从1 到 n 的 ...

1702
来自专栏数据结构与算法

洛谷P2181 对角线(组合数)

题目描述 对于一个N个定点的凸多边形,他的任何三条对角线都不会交于一点。请求楚图形中对角线交点的个数。 例如,6边形: ? 输入输出格式 输入格式: 第一行一个...

3495
来自专栏数据结构与算法

26:字符串最大跨距

26:字符串最大跨距 总时间限制: 1000ms 内存限制: 65536kB描述 有三个字符串S,S1,S2,其中,S长度不超过300,S1和S2的长度不超过...

4418

扫码关注云+社区

领取腾讯云代金券