C++使用类和对象
1、 内置函数
程序调用函数时需要一定的时间和空间开销,其执行过程一般如下:
而C++提供了一种高效率的方法,即在编译的时候将所调用函数的代码直接嵌入到主函数中,而不是将流程转出去,这样可以避免函数调用时频繁的转入与转出操作,从而节省过程中“保存现场”和“恢复现场”所需的时间。如下代码:
#include<iostream>
using namespace std;
inline int max(int,int,int);
int main()
{
int i=1,j=2,k=3;
int m=max(i,j,k);
cout<<"max="<<m<<endl;
return 0;
}
inline int max(int a,int b,int c){
if(b>a)
a=b;
if(c>a)
a=c;
return a;
}
内置函数虽然节省了程序的运行时间,但会增加目表函数的长度,这也是不利的,需要综合分析后使用。
2、 成员函数
如下简单案例
#include<iostream>
#include<string>
using namespace std;
class Student{
public:
void display();
void set();
private:
int num;
char sex;
string name;
};
void Student::display()
{
cout<<"num:"<<num<<endl;
cout<<"sex:"<<sex<<endl;
cout<<"name:"<<name<<endl;
}
void Student::set()
{
cin>>num;
cin>>sex;
cin>>name;
}
int main(){
Student stu;
stu.set();
stu.display();
return 0;
}
成员函数在类外定义的时候,必须在函数名前加上类名,予以限定,“::”表示作用域限定符,用它声明函数属于哪个类。
注意:如果函数在类外定义时,系统不会将其认为是加了inline的内置函数,这些成员函数的调用和普通的函数调用相同,这样有利于类的接口和类的实现相分离,利于信息的隐藏。
3、 带参数的构造方法
以一个简单的案例说明:
#include<iostream>
#include<string>
using namespace std;
class Box
{
private:
int height;
int width;
int length;
public:
Box(int,int,int);
int volume();
};
Box::Box(int h,int w,int l){
height=h;
width=w;
length=l;
}
int Box::volume()
{
return height*length*width;
}
int main(){
Box box1(12,25,10);
cout<<"the volume of box1 is "<<box1.volume()<<endl;
return 0;
}
也可以通过参数初始化表对数据成员初始化,将类中的构造方法进行改写,如下:
class Box
{
private:
int height;
int width;
int length;
public:
Box(int h,int w,int l):height(h),width(w),length(l){};
int volume();
};
注意如果类中的数据成员是数组,则应在构造函数体中用语句对其赋值,而不能在参数初始化表中对其初始化。如下案例:
class Student
{private:
int no;
char name[20];
public:
Student(int n,char nam[]):no(n){
strcpy(name,nam);};
void display();
};
void Student::display(){
cout<<no<<" "<<name<<endl;
}
int main()
{
Student stu(1,"郭庆兴");
stu.display();
return 0;
}
或者这样
class Student
{private:
int no;
string name;
public:
Student(int n,string nam):no(n),name(nam){};
void display();
};
4、 构造函数的重载
如下面一个简单的代码案例:
#include<iostream>
#include<string>
using namespace std; class Box
{
private:
int height;
int width;
int length;
public:
Box();
Box(int h,int w,int l):height(h),width(w),length(l){};
int volume();
}; Box::Box(){
height=10;
width=10;
length=10;
} int Box::volume()
{
return height*length*width;
}
int main(){
Box box1;
cout<<"the volume of box1 is "<<box1.volume()<<endl;
Box box2(12,25,10);
cout<<"the volume of box1 is "<<box2.volume()<<endl;
return 0;
}
注意:当建立对象使用无参构造函数函数时,要注意语句的书写:
Box box1;
而不能写成:
Box box1(); //错误
以上错误的语句并不是定义Box对象,而是定义一个返回为Box的普通函数。
5、 使用默认参数构造函数
如下案例:
#include<iostream>
#include<string>
using namespace std;
class Box
{
private:
int height;
int width;
int length;
public:
Box(int h=10,int w=10,int len=10):height(h),width(w),length(len){};
int volume();
void display();
};
int Box::volume()
{
return height*length*width;
}
int main(){
Box box1;
cout<<"the volume of box1 is "<<box1.volume()<<endl;
Box box2(12,25);
cout<<"the volume of box2 is "<<box2.volume()<<endl;
Box box3(12,25,30);
cout<<"the volume of box3 is "<<box3.volume()<<endl;
return 0;
}
因此在编写设有默认参数的构造方法的时候,不可以有两个构造方法,如下:
Box(int h=10,int w=10,int len=10);
Box();
这样如果一旦执行“Box box;”,系统就不能分别是以哪个构造方法为基准建立构造函数。
6、 析构函数
析构函数是一个特殊的成员函数,它的名字是类名前面加上“~”符号。在C++中“~”是取反运算符。可以联想到它是与构造函数起相反的作用。析构函数的作用是在撤销对象占用的内存之前,完成一些清理工作。
析构函数不返回任何值,没有函数类型,也没有函数参数。由于没有函数参数,因此它并不能重载,即一个类只能有一个析构函数。
如下案例:
#include<iostream>
#include<string>
using namespace std; class Student
{private:
int no;
string name;
char sex;
public:
Student(int n,string nam,char s){
no=n;
name=nam;
sex=s;
cout<<"Constructor"<<no<<" called!"<<endl;
}
~Student(){
cout<<"Destructor"<<no<<" called!"<<endl;
}
void display(){
cout<<"no : "<<no<<endl;
cout<<"name : "<<name<<endl;
cout<<"sex : "<<sex<<endl;
}
}; int main()
{
Student stu1(1,"郭庆兴",'m');
stu1.display();
Student stu2(2,"test",'f');
stu2.display();
return 0;
}
结果如图所示:
可知,对于构造函数,程序先执行stu1的构造函数,再去执行stu2的构造函数;而对于析构函数来说,程序先执行stu2的析构函数,再去执行stu1的析构函数,这就十分类似于栈的特性了。对于“同一级别”的构造函数个析构函数是这样的,那么不同“级别”,则不是这样的,这里以局部变量和全局变量来举例。如下代码:
int main()
{
Student stu1(1,"郭庆兴",'m');
stu1.display();
static Student stu2(2,"test",'f');
stu2.display();
return 0;
}
在stu2对象前面加上一个static即可,此时stu2是静态变量,它一直到程序全部运行结束后才会释放。结果如下图:
7、 对象数组
数组不仅可以存放简单变量,还可以存放由类组成的对象。如下案例:
#include<iostream>
#include<string>
using namespace std;
class Box
{
private:
int height;
int width;
int length;
public:
Box(int h=10,int w=10,int len=10):height(h),width(w),length(len){};
int volume();
void display();
};
int Box::volume()
{
return height*length*width;
} int main(){
Box a[4]={
Box(),
Box(20),
Box(10,30),
Box(10,10,40)
};
cout<<"the volume of box1 is "<<a[0].volume()<<endl;
cout<<"the volume of box2 is "<<a[1].volume()<<endl;
cout<<"the volume of box3 is "<<a[2].volume()<<endl;
cout<<"the volume of box4 is "<<a[3].volume()<<endl;
return 0;
}
结果如图所示:
C++使用类和对象的更多相关文章
- Java编程里的类和对象
像我们搞计算机这块的,都知道这么一件事,当前的计算机编程语言主要分为两大块,一为面向过程,二为面向对象.Java就是一门纯面向对象的语言.学习了一个月左右的Java,在下对于Java当中的类和对象有了 ...
- Python - 类与对象的方法
类与对象的方法
- C++基础知识(5)---类和对象
终于把C++中的基础在前面的几篇博客中总结完了,可能还有一些语法还没有总结到,没关系,以后用到了再查资料就好.类是C++中的一个非常重要的概念,这是区别你使用的C++到底是面向过程还是面向对象的一个重 ...
- 简述JavaScript对象、数组对象与类数组对象
问题引出 在上图给出的文档中,用JavaScript获取那个a标签,要用什么办法呢?相信第一反应一定是使用document.getElementsByTagName('a')[0]来获取.同样的,在使 ...
- 前端学PHP之面向对象系列第一篇——类和对象
× 目录 [1]类 [2]成员属性[3]成员方法[4]对象[5]成员访问[6]this 前面的话 面向对象程序设计(OOP)是一种计算机编程架构.计算机程序由单个能够起到子程序作用的单元或对象组成,为 ...
- Objective-C Runtime 运行时之一:类与对象
Objective-C语言是一门动态语言,它将很多静态语言在编译和链接时期做的事放到了运行时来处理.这种动态语言的优势在于:我们写代码时更具灵活性,如我们可以把消息转发给我们想要的对象,或者随意交换一 ...
- [Java入门笔记] 面向对象编程基础(一):类和对象
什么是面向对象编程? 我们先来看看几个概念: 面向过程程序设计 面向过程,是根据事情发展的步骤,按进行的顺序过程划分,面向过程其实是最为实际的一种思考方式,可以说面向过程是一种基础的方法,它考虑的是实 ...
- 解析Java类和对象的初始化过程
类的初始化和对象初始化是 JVM 管理的类型生命周期中非常重要的两个环节,Google 了一遍网络,有关类装载机制的文章倒是不少,然而类初始化和对象初始化的文章并不多,特别是从字节码和 JVM 层次来 ...
- 02OC的类和对象
这章重点介绍OC的类以及对象,由于C语言是面向过程语言,而OC只是对于C语言多了一些面向对象的特性,所以OC相对于其他面向对象语言,例如C#.Java等没有那么多的语法特性,所以差别还是比较大的. 一 ...
- swift基础:第六部分:类与对象
http://reactnative.cn/docs/0.24/getting-started.html#content(react Native 开发文档) 互联网这个时代,你松懈一天,就会有很多很 ...
随机推荐
- SharePoint 2013 页面访问,Url中间多一段"_layouts/15/start.aspx#"
问题描述: 我想访问如下页面 http://Host/_layouts/15/ManageFeatures.aspx 点击以后页面地址没有错,但是中间多了一段"_layouts/15/sta ...
- Lease问题
经过查明原来是lease引发的问题.不过查问题的过程让我们耽误了很多修复故障的时间,很是不爽. 起因:datanode和regionserver以及master同时挂掉 现象:datanode重启后, ...
- ruby中如何调用与局部变量同名的私有方法
如果ruby中一个局部变量名和私有方法名同名的话,默认该名称被解释为变量而不是方法: x=10; def x;puts "what?" end 当你输入x实际不能执行x方法.解释器 ...
- Android开发学习总结(二)——使用Android Studio搭建Android集成开发环境
有很长一段时间没有更新博客了,最近实在是太忙了,没有时间去总结,现在终于可以有时间去总结一些Android上面的东西了,很久以前写过这篇关于使用Android Studio搭建Android集成开发环 ...
- Java不走弯路教程(6.JDBC)
6.JDBC 在上一章,我们完成了MyDb数据库的简单的客户段调用.作为产品我们还封装了驱动程序,并且提供了统一的调用接口. 大家应该知道,市面上有多种数据库产品,比如Oracle,Mysql,DB2 ...
- [ SSH框架 ] Hibernate框架学习之三
一.表关系的分析 Hibernate框架实现了ORM的思想,将关系数据库中表的数据映射成对象,使开发人员把对数据库的操作转化为对对象的操作,Hibernate的关联关系映射主要包括多表的映射配置.数据 ...
- add two numbers(将两个链表相加)
You are given two non-empty linked lists representing two non-negative integers. The digits are stor ...
- Spring多数据源解决方案
Figure 2 多数据源的选择逻辑渗透至客户端 解决方案 Figure 3 采用Proxy模式来封转数据源选择逻辑 通过采用Proxy模式我们在方案实现中实现一个虚拟的数据源.并且通过它来封装数据源 ...
- Ribbon整合Eureka组件,以实现负载均衡
1整体框架的说明 在本案例的框架里,我们将配置一个Eureka服务器,搭建三个提供相同服务的Eureka服务提供者,同时在Eureka服务调用者里引入Ribbon组件,这样,当有多个url向服务调用者 ...
- git merge 与 git rebase
git merge git rebase merge V.S. rebase 参考材料 写在开始: 对merge和rebase的用法总有疑惑,好像两个都能完成"获取别的branch的comm ...