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);//错误,出现歧义
- 使用xUnit为.net core程序进行单元测试(4)
- 使用xUnit为.net core程序进行单元测试(3)
- 使用xUnit为.net core程序进行单元测试(2)
- 使用xUnit为.net core程序进行单元测试(1)
- 用 Identity Server 4 (JWKS 端点和 RS256 算法) 来保护 Python web api
- asp.net core 2.0 查缺补漏
- SQL Server 性能优化之——T-SQL NOT IN 和 NOT Exists
- SQL Server 性能优化之——重复索引
- SQL Server 性能优化之——系统化方法提高性能
- C# 调用PowerShell方法
- 使用Visual Studio 2010 一步一步创建Powershell Module 和 Cmdlet
- [SQLServer大对象]——FileTable初体验
- JavaScript闭包,只学这篇就会了
- [数据库基础]——编码标准之格式
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 【C语言简单说】二十一:双重指针基础 (完结)
- 有关 php __autoload 自动加载类函数的用法
- sql 子查询(mysql)
- php 使用PDO,防止sql注入 简单说明
- js (javascript) 中获取年月日信息
- js(javascript)取得当前时间小时,分钟,秒 以及毫秒
- js(javascript) onclick与ondblclick 单击与双击事件
- unity5.x C# 获取屏幕宽度 设置不受重力影响
- unity5.x Translate平移移动 以及GetComponent获取组件
- php 计时器microtime 以及去掉数组重复值array_unique
- php 字符串打散为数组,用逗号分隔出数组
- php in_array 判断数组中是否存在此元素
- php str_replace 字符串替换
- strstr和strcchr查找字符串和区别
- php获取当前操作系统类型 PHP_OS