c++类的学习笔记
用结构体数据的安全性得不到保证。
使用类对数据进行封装,只能通过函数修改类中的数据
(1)类的定义
class 类名
{
private:
protected:
public:
};
private:定义私有成员,只能被类本身的成员函数和友元访问。派生类和其他类均不能访问。若数据没有指明类型,默认为私有。
public:定义公有成员,可被程序中任何代码访问。
protected:定义保护成员,能被本身成员函数,友元,派生类访问。
(2)成员函数的定义
a、在类中定义
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std; class Student
{
private:
string Name;
float Phi,Math,Ave;
public:
void set(string name,float phi,float math)
{
Name=name;
Phi=phi;
Math=math;
}
void Average()
{
Ave=(Phi+Math)/;
}
void Display()
{
cout<<Name<<" "<<Phi<<" "<<Math<<" "<<Ave;
}
}; int main()
{
Student stud;
stud.set("zhangsan",,);
stud.Average();
stud.Display();
return ;
}
b、在类外定义
(考虑到有些函数复杂,在类内写不好看)
先在类内声明,然后在类外定义的形式是
函数返回值类型 类名 ::函数名称()
{}
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std; class Date
{
private :
int year,month,day;
public:
void setDate(int,int,int);
bool IsLeap();
void print()
{
cout<<year<<" "<<month<<" "<<day<<endl;
}
}; void Date::setDate(int n,int y,int r)
{
year=n;month=y;day=r;
} bool Date::IsLeap()
{
if(year%==||year%==&&year%) return true;
return false;
} int main()
{
Date dt;
dt.setDate(,,);
if(dt.IsLeap()) cout<<"yes\n";
else cout<<"no\n";
dt.print();
return ;
}
(3)成员的访问
a、对于数据成员的访问
对象名.成员名 对象指针名->成员名 (*对象指针名).成员名
b、对于成员函数的访问
对象名.成员函数名(参数表) 对象指针名->成员函数名(参数表) (*对象指针名).成员函数名(参数表)
#include<iostream>
#include<cstdio>
using namespace std; class Student
{
private :
string name;
float Math,Phi,Ave;
public:
void setDate(string nam,float math,float phi)
{
name=nam;
Math=math;
Phi=phi;
}
void Average()
{
Ave=(Math+Phi)/;
}
void print()
{
cout<<name<<" "<<Math<<" "<<Phi<<" "<<Ave<<endl;
}
}; int main()
{
Student stu,*stud;
stud=&stu;
//一开始我没定义 stu,直接定义个指针用了,这样不行。
stud->setDate("zhangsan",,);
stud->Average();
stud->print();
return ;
}
#include<iostream>
#include<cstdio>
using namespace std; class Student
{
private:
string Name;
int Phi,Math;
public:
void setDate();
void print()
{
cout<<Name<<" "<<Phi<<" "<<Math<<endl;
}
}; void Student::setDate()//在类作用域内,直接使用即可访问
{
cin>>Name>>Phi>>Math;
} int main()
{
Student stud;
stud.setDate();
stud.print();
return ;
}
(4)构造函数
构造函数就是对类内的数据初始化,定义一个类的对象时自动调用,如果不写构造函数,就调用系统默认的构造函数。
性质:与类名相同 无返回值 可以重载
#include<iostream>
#include<cstdio>
using namespace std; class Cuboid //长方体类
{
private:
int length,width,height;
public:
Cuboid();//无参构造函数
Cuboid(int,int,int);//有参构造函数
int volume();//计算体积
}; Cuboid::Cuboid()
{
length=width=height=;
} Cuboid::Cuboid(int l,int w,int h)
{
length=l;
width=w;
height=h;
} int Cuboid::volume()
{
return length*width*height;
} int main()
{
Cuboid cuboid1;
cout<<"cuboid1的体积为:"<<cuboid1.volume()<<endl;
Cuboid cuboid2(,,);
cout<<"cuboid2的体积为:"<<cuboid2.volume()<<endl;
return ;
}
#include<iostream>
#include<cstdio>
using namespace std; class Cuboid
{
private:
int h,w,l;
public:
/* Cuboid(int hh=10,int ww=20,int ll=30)另一种写法
{
h=hh;w=ww;l=ll;
}*/
Cuboid(int hh=,int ww=,int ll=);//声明时有默认参数
int volume()
{
return h*w*l;
}
}; Cuboid::Cuboid(int hh,int ww,int ll)//不用再写默认参数
{
h=hh;
w=ww;
l=ll;
} int main()
{
Cuboid cuboid1;
cout<<cuboid1.volume()<<endl;
Cuboid cuboid2();
cout<<cuboid2.volume()<<endl;
Cuboid cuboid3(,);
cout<<cuboid3.volume()<<endl;
return ;
}
也可以这样初始化
Cuboid(int h,int w,int len):height(h),width(w),length(len){}
(5)拷贝构造函数
拷贝构造函数的名称与类名一致,函数的形式参数是本类型的一个引用变量。
Sample (Sample &S);
对象1=对象2 //对象1和对象2必须是同一个类
将一个对象的非静态数据成员的值一一赋值给另一对象的对应成员。
Sample S2(S1);
Sample S2=S1;两者等价
a、
#include<iostream>
#include<cstdio>
using namespace std; class Sample
{
private:
int data;
public:
Sample(int dt)
{
data=dt;
}
void print()
{
cout<<data<<endl;
}
}; int main()
{
Sample s1();
Sample s2=s1;
s2.print();
}
b、自定义拷贝构造函数 并不是一一赋值
#include<iostream>
#include<cstdio>
using namespace std; class Sample
{
private:
int a,b,c,d;
public:
Sample(int aa,int bb,int cc,int dd)
{
a=aa;b=bb;c=cc;d=dd;
}
Sample(Sample &S)
{
a=S.a;b=S.b;c=S.c; d=S.d+;
}
void print()
{
cout<<a<<" "<<b<<" "<<c<<" "<<d<<endl;
}
}; int main()
{
Sample dt1(,,,);
Sample dt2=dt1;
//Sample dt2(dt1);
dt2.print();
return ;
}
(6)析构函数
作用在对象脱离作用域时释放相关资源,清理善后工作。
析构函数名和类名相同只是在函数名前面加~符号
无参数 无返回值 只能有一个析构函数 不写虚构函数调用系统自己的
#include<iostream>
#include<cstdio>
using namespace std; class Cstudent
{
private:
int num;
string name;
public:
Cstudent(string nam,int nnum)
{
name=nam;
num=nnum;
cout<<name<<" Constructor called.\n";
}
void display()
{
cout<<"学号:"<<num<<endl;
cout<<"姓名:"<<name<<endl;
}
~Cstudent()
{
cout<<name<<" Destructor called\n";
}
}; int main()
{
Cstudent stud1("zhangsan",);
Cstudent stud2("lisi",);
return ;
}
一般情况下,调用析构函数的次序与调用构造函数的次序相反。
(7)静态成员--静态数据成员
静态数据成员被类内所有的对象共享,某个对象对静态数据成员做出修改,则其他所有对象也共享被修改后的值。
静态数据成员的存储空间不会随着对象的产生而分配,也不会随着对象的消失而释放。
因此,静态数据成员不能在类体内初始化。
如果未对静态数据成员赋初值,默认为0;其他成员不会默认为0;
class Cstudent
{
private:
string name;
int score;
static int studenttotal;
static int sumscore;
public:
Cstudent(string nam,int scor)
{
name=nam;
score=scor;
studenttotal++;
sumscore+=scor;
cout<<name<<" Constructor called.\n";
}
static float average();
~Cstudent();
}; int Cstudent::studenttotal=; int Cstudent::sumscore=;
(8)静态成员--静态成员函数
一般情况下,静态成员函数只访问静态成员。也可以访问非静态成员,但要指明其所属对象,但这样麻烦,所以不用。
class Cstudent
{
private:
string name;
int score;
static int studenttotal;
static int sumscore;
public:
Cstudent(string nam,int scor)
{
name=nam;
score=scor;
studenttotal++;
sumscore+=scor;
cout<<name<<" Constructor called.\n";
}
static float average();//*******
~Cstudent();
}; int Cstudent::studenttotal=; int Cstudent::sumscore=; float Cstudent::average() //**********
{
return (sumscore*./studenttotal);
}
静态成员的访问
一般是:类名::静态数据成员名
#include<iostream>
#include<cstdio>
using namespace std; class Cstudent
{
private:
string name;
int score;
static int studenttotal;
static int sumscore;
public:
Cstudent(string nam,int scor)
{
name=nam;
score=scor;
studenttotal++;
sumscore+=scor;
cout<<name<<" Constructor called.\n";
}
static float average();//*******
~Cstudent();
}; int Cstudent::studenttotal=; int Cstudent::sumscore=; float Cstudent::average() //**********
{
return (sumscore*./studenttotal);
} Cstudent::~Cstudent()
{
studenttotal--;
sumscore-=score;
cout<<name<<" Destructor called.\n";
} int main()
{
Cstudent stud[]={Cstudent("zhangsan",),Cstudent("wangwu",)};
cout<<Cstudent::average()<<endl;
return ;
}
(9)对象的存储
只有数据成员占有的内存空间的大小,而没有包括成员函数。
//类的空间
#include<iostream>
#include<cstdio>
using namespace std; class Data
{
private:
int a,b;
public:
void setdata(int aa,int bb)
{
a=aa;
b=bb;
}
void print()
{
cout<<a<<" "<<b<<endl;
} }; int main()
{
Data x,y;
cout<<sizeof(int)<<endl;
cout<<sizeof(x)<<endl;
return ;
}
()
(10)this指针
this指针指向正在操作该成员函数的对象。
this指针最常用的两种情况:
①该函数的返回的是对调用该函数的对象的引用 即return *this
②当参数与成员变量名相同时,由于参数优先,所以对数据成员必须显式使用this指针修饰。
//this指针
#include<iostream>
#include<cstdio>
using namespace std; class Point
{
private:
int x,y;
public:
Point(int xx,int yy)
{
x=xx;y=yy;
}
Point& setPoint(int x,int y)
{
this->x=x+;
(*this).y=y+;
return *this;
}
int getX(){return x;}
int getY(){return y;}
}; int main()
{
Point p1(,);
cout<<"执行setPoint()前p1:"<<p1.getX()<<","<<p1.getY()<<endl;
//cout<<p1.setPoint(8,8);这行是错的
p1.setPoint(,);
//p1=p1.setPoint(8,8);和上一行等价
cout<<"执行setPoint()后p1:"<<p1.getX()<<","<<p1.getY()<<endl;
return ;
(11)常对象
常对象是指对象的数据成员的值不能被改变,常对象必须在定义的同时进行初始化。
且一旦定义就不能再改变。常对象只能调用const成员函数。普通对象可以调用const成员函数。
//常对象
#include<iostream>
#include<cstdio>
using namespace std; class Rectangle
{
private:
int width;
int length;
public:
Rectangle()
{
width=;
length=;
}
Rectangle(int w,int len)
{
width=w;length=len;
}
int area() const
{
return width*length;
}
}; int main()
{
Rectangle r1(,);
const Rectangle r2(,);
//Rectangle const r2(6,8);等价
cout<<"r1的面积:"<<r1.area()<<endl;
cout<<"r2的面积:"<<r2.area()<<endl;
return ;
}
常对象中的某个数据成员想要修改,则声明为mutable
//常对象
#include<iostream>
#include<cstdio>
using namespace std; class Rectangle
{
private:
int width;
mutable int length;
public:
Rectangle()
{
width=;
length=;
}
Rectangle(int w,int len)
{
width=w;length=len;
}
int area() const
{
length*=;
return width*length;
}
}; int main()
{
Rectangle r1(,);
const Rectangle r2(,);
//Rectangle const r2(6,8);等价
cout<<"r1的面积:"<<r1.area()<<endl;
cout<<"r2的面积:"<<r2.area()<<endl;
return ;
}
指向常对象的指针变量
const 类名 *指针变量名
const Rectangle *ptr=&r1;
不能通过ptr修改r1,但ptr也可以指向别的。
(12)常数据成员
将数据成员声明为const型。不能被赋值,类体类外函数只可读。
对常数据成员的初始化用构造函数的初始化列表。
const int Length;
Rectangle(int w,int len):Length(len)
{Width=w;}
(13)常成员函数
这些函数只是可读函数,不改变类的数据成员,对函数加上const关键字标识,提高程序的可读性。
#include<iostream>
#include<cstdio>
using namespace std; class Rectangle
{
private:
int width,length;
public:
Rectangle(int w,int len)
{
width=w;
length=len;
}
int area()const;
void print()
{
cout<<"print"<<endl;
}
}; int Rectangle::area()const
{
//width=10;不可修改数据成员
//print();常成员函数不能调用非const型成员函数
return width*length;
} int main()
{
Rectangle r(,);
cout<<r.area()<<endl;
return ;
}
(14)常指针
将指针变量声明为const,这样指针始终保持其初值,不会改变。
#include<iostream>
#include<cstdio>
using namespace std; class Rectangle
{
private:
int width,length;
public:
Rectangle(int w,int len)
{
width=w;
length=len;
}
int area()
{
return width*length;
}
}; int main()
{
Rectangle r1(,);
Rectangle *const ptr=&r1;
cout<<ptr->area();
// Rectangle r2(3,3);不可以改变常指针的值
// ptr=&r2;
return ;
}
(15)常引用
一个变量的引用就是这个变量的别名。
变量名和引用名都指向同一段内存单元。
如果形参为变量的引用名,实参为变量名,则在调用时虚实结合,
并不是为形参新开辟了空间,而是把实参变量地址传给形参。
如果不希望在函数中修改实参的值,则可以把引用变量名声明为常引用。
#include<iostream>
#include<cstdio>
using namespace std; class Rectangle
{
private:
int width,length;
public:
Rectangle(int w,int len)
{
width=w;
length=len;
}
void setWL(int w,int len)
{
width=w;
length=len;
}
int area()
{
return width*length;
}
}; void setRec(Rectangle &r1)
{
r1.setWL(,);
} int main()
{
Rectangle r(,);
cout<<r.area()<<endl;
setRec(r);
cout<<r.area()<<endl;
return ;
}
若是常引用,则不可以修改。
(16)友元
c++用关键字 friend声明类的友元
①位于一个函数说明语句之前,指出该函数为这个类的友元函数。
②位于一个类名之前,指出该类是这个类的友元。
如果要允许一个不属于类的函数取该类中的数据
法一:数据成员声明为共有
法二:将类内部声明这个函数为友元,可以访问该类数据。
后者更好。友元其实破坏了类的封装。
友元函数是普通(全局)函数
//友元
#include<iostream>
#include<cstdio>
using namespace std; class Rectangle
{
private:
int width,length;
public:
Rectangle(int w,int len)
{
width=w;
length=len;
}
int area()
{
return width*length;
}
friend void display(Rectangle &r1);
}; void display(Rectangle &r1)//必须要加&
{
cout<<r1.length<<" "<<r1.width<<endl;//不能直接使用length必须通过对象使用
cout<<r1.area()<<endl;
} int main()
{
Rectangle r(,);
display(r);
return ;
}
友元函数是其他类的成员函数
#include<iostream>
#include<cstdio>
using namespace std;
class Rectangle;//提前引用说明
class Cuboid
{
private:
int Height;
public:
Cuboid(int h)
{
Height=h;
}
int Volume(Rectangle &r);//此处只能声明,不能定义。因为Rectangle类还未定义
}; class Rectangle
{
private:
int width,length;
public:
Rectangle(int w,int len)
{
width=w;length=len;
}
friend int Cuboid::Volume(Rectangle &r);
}; int Cuboid::Volume(Rectangle &r)
{
return r.length*r.width*Height;
} int main()
{
Rectangle R(,);
Cuboid C();
cout<<"长方体的体积为:"<<C.Volume(R)<<endl;
return ;
}
(17)友元类
C++中允许将一个类声明为另一个类的友元,称为友元类。友元类中的所有成员
函数都可以访问另一个类中的私有成员或保护乘员
#include<iostream>
#include<cstdio>
using namespace std; class Rectangle; class Cuboid
{
private:
int Height;
public:
Cuboid(int h)
{
Height=h;
}
int Volume(Rectangle &r);
}; class Rectangle
{
private:
int width,length;
public:
Rectangle(int w,int len)
{
width=w;
length=len;
}
friend class Cuboid;
}; int Cuboid::Volume(Rectangle &r)
{
return r.length*r.width*Height;
} int main()
{
Rectangle r(,);
Cuboid C();
cout<<"长方体的体积为:"<<C.Volume(r);
return ;
}
(18)类模板
看不下去了。直接抄。
class A
{
private:
int x,y;
public:
A(int xx,int yy){x=xx;y=yy;}
int sum(){return x+y;}
}; class A
{
private:
double x,y;
public:
A(double xx,double yy){x=xx;y=yy;}
double sum(){return x+y;}
};
两段代码只是数据类型不同,但做的工作是重复的。
类模板是一系列相关类的模型或样板,这些类的成员组成相同,成员函数的源代码形式相同。所不同的只是类型。
(成员的类型以及成员函数的参数类型)。对于类模板,数据类型成了它的参数,因而是一种类型参数化的类。
类模板是类的抽象,类是类模板的实例。
template<class T>
class A
{
private:
T x,y;
public:
A(T xx,T yy){x=xx;y=yy;}
T sum(){return x+y;}
};
template<模板参数表>
class 类模板名
{}
class也可用typename关键字代替
类模板不能直接生成对象,因为其参数类型是不确定的,故需要首先对模板参数指定“实参”
类模板名<具体类型>对象名{(构造函数实参列表)}
A<int>IntA(6,8);
A<double>DoubleA(6.6,8.8)
若函数在类外定义
T A<T>::sum()
{return x+y;}
c++类的学习笔记的更多相关文章
- python 面向对象(类)--学习笔记
面向对象是一种编程方式, 主要集中在类和对象的两个概念 python 中的类符合封装, 继承, 多态的特征 类 是一个模板, 是n多函数的集成 对象 是类的实例化 类的成员分为三大类:字段.方法.属性 ...
- Java sun.misc.Unsafe类的学习笔记
Java未开源的Unsafe类 Unsafe类可以为我们提供高效并且线程安全方式操作变量,直接和内存数据打交道. 获取Unsafe实体的方法 private static Unsafe getUnsa ...
- 初步C++类模板学习笔记
类模板 实现:在上课时间的定义给它的一个或多个参数,这些参数代表了不同的数据类型. -->抽象的类. 在调用类模板时, 指定參数, 由编 ...
- 初探C++类模版学习笔记
类模板 实现:在定义类的时候给它一个或多个參数,这个些參数表示不同的数据类型. -->抽象的类. 在调用类模板时, 指定參数, 由编译系 ...
- 《C++ Primer Plus》14.4 类模板 学习笔记
14.4.1 定义类模板下面以第10章的Stack类为基础来建立模板.原来的类声明如下:typedef unsigned long Item; class Stack{private: enum ...
- JavaScript匿名类整理学习笔记
以下为总结在开源的JavaScript框架中能看到很多这样语法结构(function(){})()比如我最近看的jQuery,及chediter.刚开始的时候我看到这样的结果有点奇怪,它是怎么执行的, ...
- 3.4常用类(java学习笔记)Math和Random
一.Math 这个类包含执行指数.对数.平方根法.三角函数等基本的数字运算. Math中还包含一些静态常量供我们调用. 如PI圆周率,E. 1.abs(),返回该数的绝对值. public class ...
- UML类图学习笔记
http://note.youdao.com/noteshare?id=d5af220db7081dda73511fcb7b4da390
- GUI学习之五——QAbstractButton类学习笔记
今天总结一下AbstractButton类的学习笔记. 一.描述 AbstractButton是对各种按键的抽象类他的继承关系是这样的 首先,QAbstractButton继承了QWidget类的各种 ...
随机推荐
- OpenDaylight开发hello-world项目之功能实现
OpenDaylight开发hello-world项目之开发环境搭建 OpenDaylight开发hello-world项目之开发工具安装 OpenDaylight开发hello-world项目之代码 ...
- xml模块(了解)
目录 一.xml简介 二.Python使用xml 三.自己创建xml文档 一.xml简介 xml是实现不同语言或程序之间进行数据交换的协议,跟json差不多,但json使用起来更简单,不过,古时候,在 ...
- python 学习(day1)
初识python python的创始人为吉多*范罗苏姆(Guido van Rossum).1989年圣诞节期间,开发出来的脚本解释程序. python是⼀⻔什么样的语言 python 是一门解释型语 ...
- ES5提取公共变量
在ES5中,请求地址前缀等需要作为公共变量提出. 则需在common.js写上 Object.defineProperty(window,'base',{ value:"http://xx. ...
- 《细说PHP》第四版 样章 第23章 自定义PHP接口规范 8
23.5.2 架构详解 本例的实现最重要的就是服务层的设计,有两个配置文件config.php和api.php,其中文件config.php是全局的配置文件,用于整个程序全局需要的参数设置.可以根据 ...
- Linux 内存释放
简介 linux 内存释放通过如下命令,将cache与buff根据环境进行释放操作,避免重启释放内存. 操作 1.将内存中buff数据保存磁盘 sync 2.清理cache与buff缓存 echo 3 ...
- 用PHP写出计算器
<body> <?php if (!empty($_POST)) { $op=$_POST['point']; $sum1 = $_POST['sum1']; $sum2 = $_P ...
- PHP odbc_errormsg ODBC 函数
定义和用法 odbc_errormsg - 获取最后一条错误消息 语法 odbc_errormsg ( [ resource $connection_id ] ) 返回包含最后一个ODBC错误消息的字 ...
- js addEventListener事件多次绑定问题
如果为了避免 js addEventListener事件多次绑定问题,可以使用.onclick直接绑定,后一次click绑定会覆盖调前一次.
- JavaScript 错误异常
JavaScript 错误异常 错误异常语句 try 语句测试代码块中的错误 catch 语句处理错误 throw 语句允许自定义错误 finally 语句在错误异常语句后,必须执行的代码块 try ...