由于自己本人上课不太认真,只能靠自己学习例题总结。
希望能给大家一些便捷,让大家开心学习C++。
对象的创建与使用:
例题5-1 定义一个点类,生成对象,将点的坐标显示在屏幕上:
#include<iostream>
using namespace std;
class Point{
int x,y;
public:
void setXY(int a,int b){
x=a;
y=b;
}
int getX(){
return x;
}int getY(){
return y;
}
};
int main()
{
Point p1,p2;
p1.setXY(1,2);
p2.setXY(3,4);
cout<<"点p1的x坐标为:"<<p1.getX()<<endl;
cout<<"点p1的y坐标为:"<<p1.getY()<<endl;
cout<<"点p2的坐标为:("<<p2.getX()<<","<<p2.getY()<<")"<<endl;
return 0;
}
例题5-2 观察类的所占的字节:
#include<iostream>
using namespace std;
class A{
int x;
public:
void setX(int b){
x=b;
}
};
int main(){
A a;
cout<<sizeof(int)<<endl<<sizeof(a)<<endl;
return 0;
}
类成员的访问能力
例题5-3:观察类成员访问控制能力:
#include<iostream>
using namespace std;
class A{
private:
int i;
public:
char c;
public:
void setI(int j){
i=j;
}
void display(){
cout<<"i="<<i<<endl<<"C="<<c<<endl;
}
};
class B{
public:
char c;
public:
void display(){
cout<<"c="<<c<<endl;
}
};
int main(){
A a;
B b;
//a.i=1; error
a.c='e';b.c='f'; //ok
a.setI(8); //通过接口访问公有成员
a.display(); //ok
b.display();
return 0;
}
通过这个例子容易看出来:其实对于类来说 :在类外面只能访问公有的成员。
但是对于要访问私有成员:需要利用公有成员函数间接调用。
实例1:设计一个圆Circle类,能够求出圆的面积:
#include<iostream>
#include<cmath>
using namespace std;
const double Pi=acos(-1);
class Circle{
private:
double m_r;
public:
void setR(double r){
m_r=r;
}
double getR(){
return m_r;
}double getArea(){
return Pi*m_r*m_r;
}
};
int main()
{
Circle c;
c.setR(3);
cout<<"Circle's r is "<<c.getR()<<endl;
cout<<"Circle's area is "<<c.getArea()<<endl;
return 0;
}
通过这个实例其实可以看出来:
调用公有的成员函数或者变量:直接用 “.”来实现好比C语言里的结构体。
实例2:设计一个数字时钟,可以设置时间和显示时间
#include<iostream>
using namespace std;
class Clock{
private:
int h;
int m;
int sec;
public:
void setTime(int nh,int nm,int ns){
h=nh;
m=nm;
sec=ns;
if(h<0||h>23||m<0||m>59||sec<0||sec>59){
cout<<"illegal! time"<<endl;
exit(1);
}
}
void showTime(){
cout<<h<<":"<<m<<":"<<sec<<endl;
}
};
int main(){
Clock a;
a.setTime(14,1,2);
a.showTime();
return 0;
}
类的信息隐藏
由于为了实现利用类的接口,需要把设置 .h 和 .cpp 两个文件来分别实现。
.h 负责实现提供类的声明和类函数的实现,
.cpp 负责利用类对应的接口函数来实现对应功能即可.
建立2个文件,分别存放长方形Rectangle 类的声明和实现、类的使用。
//#ifndef RECTANGLE_H_INCLUDED
//#define RECTANGLE_H_INCLUDED
class Rectangle{
int len,w;
public:
void setL(int len);
void setW(int w);
int getL();
int getW();
int getArea();
};
//#endif // RECTANGLE_H_INCLUDED
#include"Rectangle.h"
#include<iostream>
using namespace std;
void Rectangle::setL(int L){
len=L;
if(L<0){
printf("L:illegal!\n");
exit(1);
}
}
void Rectangle::setW(int W){
w=W;
if(W<0){
printf("W:illegal!\n");
exit(1);
}
}
int Rectangle::getL(){
return len;
}
int Rectangle::getW(){
return w;
}
int Rectangle::getArea(){
return len*w;
}
int main(){
Rectangle A;
A.setL(10);
A.setW(20);
cout<<"L: "<<A.getL()<<endl;
cout<<"W: "<<A.getW()<<endl;
cout<<"Area: "<<A.getArea()<<endl;
return 0;
}
对象的初始化与消亡:
构造函数
由于类的复杂性,有必要专门设计一个函数来进行对象的初始化工作,
引例:初始化时刻需要做点是什么.如定义了一个新的对象时,需要设计一些提示词:
如“创建完成,目前是第N个对象”.
一个简单的例子:
#include<iostream>
using namespace std;
class A{
int i;
public:
A(){
i=0;
cout<<"无参析构函数被调用"<<"i="<<i<<endl;
}
A(int k){
i=k;
cout<<"带参析构函数被调用"<<"i="<<i<<endl;
}
};
int main(){
A a1;
A a2(2);
return 0;
}
析构函数:
#include<iostream>
using namespace std;
class A{
int i;
public:
A(int k=0){
i=k;
cout<<"带参构造函数调用"<<"i="<<i<<endl;
}
~A(){
cout<<"析构函数被调用"<<endl;
}
};
void fun(){
A a(8);
}
int main()
{
A a,a1(2);
fun();
return 0;
}
实例:建立一个类Person(人),在屏幕上显示出基本信息:
#include<iostream>
#include<string.h>
using namespace std;
class Person{
char *namePtr;
bool sex;
int age;
public:
Person(char *name,bool sex,int age);
~Person();
void display();
};
Person::Person(char *p,bool s,int a){
namePtr = new char [strlen(p)+1];
strcpy(namePtr,p);
sex=s;
age=a;
}
Person::~Person(){
delete []namePtr;
}
void Person::display(){
if(sex){
cout<<namePtr<<",男,"<<age<<"岁\n";
}
else{
cout<<namePtr<<",女,"<<age<<"岁\n";
}
}
int main(){
char *p1={"wang fang"},*p2={"li si"};
Person ps1(p1,false ,18),ps2(p2,true,22);
ps1.display();
ps2.display();
return 0;
}
对象的赋值与复制
例子、对象的赋值:
#include<iostream>
using namespace std;
class A{
int i;
char c;
public:
A(int j=0,char d='*'){
i=j;c=d;
}
void display(){
cout<<"i="<<i<<'\t'<<"c="<<c<<endl;
}
};
int main(){
A a1,a2(1,'#');
a1.display();
a2.display();
a1=a2;
a2=A(2,'@');
cout<<"赋值后:\n";
a1.display();
a2.display();
return 0;
}
对象的复制
复制构造函数
#include<iostream>
using namespace std;
class A{
int i;
char c;
public:
A(int j=0,char d='*'){
i=j;c=d;
}
void display(){
cout<<"i="<<i<<'\t'<<"c="<<c<<endl;
}
};
int main(){
A a1,a2(1,'#');
a1.display();
a2.display();
a1=a2;
a2=A(2,'@');
cout<<"赋值后:\n";
a1.display();
a2.display();
return 0;
}
例题5-9:浅复制示例。
某工厂生产了一批产品,所有产品质量属性默认为Good,若检测到某件产品质量有问题,应将质量属性改为Poor。
#include<iostream>
#include<string>
#include<string.h>
using namespace std;
class Product{
char * ptr;
public:
Product (char * q){
ptr=new char [strlen(q)+1];
strcpy(ptr,q);
cout<<"调用构造函数!!!"<<endl;
}
void change( char *newq){
strcpy(ptr,newq);
}
void display(){
cout<<ptr<<endl;
}
};
int main(){
Product b1("Good"),b2(b1);
cout<<"产品检测前:"<<endl;
cout<<"b1的质量"<<endl;
b1.display();
cout<<"b2的质量"<<endl;
b2.display();
cout<<"产品检测后:"<<endl;
b2.change("Poor");
cout<<"b1的质量"<<endl;
b1.display();
cout<<"b2的质量"<<endl;
b2.display();
return 0;
}
其实大家也可以看到:要是浅复制其实就是利用指针指向同一份数据,要是销毁一份数据,那么其他数据进行销毁
直接跳出系统。
例题5-10 深复制
深复制的要领:
开辟一个指针区域,把每一块对应开辟New,对应复制内容即可。
#include<iostream>
#include<string.h>
using namespace std;
class Product{
char *ptr;
public:
Product (char *q){
ptr=new char [strlen(q)+10];
strcpy(ptr,q);
}
Product(const Product &q){
ptr=new char [strlen(q.ptr)+10];
strcpy(ptr,q.ptr);
}
~Product(){
delete []ptr;
}
void change(char *q){
strcpy(ptr,q);
}
void display(){
cout<<ptr<<endl;
}
};
int main(){
Product b1("Good"),b2(b1);
cout<<"产品检测前:\n";
cout<<"b1的质量:";
b1.display();
cout<<"b2的质量:";
b2.display();
b2.change("Poor");
cout<<"产品检测后:\n";
cout<<"b1的质量:";
b1.display();
cout<<"b2的质量:";
b2.display();
return 0;
}
复制函数被调用的三种情况
(1)、当用一个对象去初始化该类的另一个对象是。
(2)、当调用的函数形参是类的对象,在实参传值给形参是。
(3)、当调用的函数返回值是类的对象,在执行return语句向调用折传送对象时。
例题如下:
#include<iostream>
using namespace std;
class A{
int i;
public:
A(int k=0){
i=k;
cout<<"调用了构造函数!!!!!!11"<<endl;
}
A(const A& q){
i=q.i;
cout<<"调用了复制构造函数!!!!~~~~"<<endl;
}
~A(){
cout<<"调用了析构函数"<<endl;
}
};
void fun1(A x){}
A fun2(){
A y;
return y;
}
int main(){
A a1(2);
fun1(a1);
A a2=fun2();
return 0;
}
实例:圆类Circle,设计一个比较两个圆的大小.
#include<iostream>
using namespace std;
class Circle{
double R;
public:
Circle(double r=1.0){
R=r;
}
double getR(){
return R;
}
bool isLargerThan(Circle q){
return (R-q.R)>0;
}
};
int main()
{
Circle c1(2.0),c2(8.0);
if(c2.isLargerThan(c1)){
cout<<"c1<c2"<<endl;
}else{
cout<<"c1>c2"<<endl;
}
return 0;
}
对象数组
定义:
#include<iostream>
using namespace std;
class A{
int i;
public:
A(int k=0){
i=k;
}
void show(){
cout<<"i="<<i<<endl;
}
};
int main()
{
A a[3];
A arr[3]={ A(1) };
A array[3]={A(1),A(2),A(3)};
for(int i=0;i<3;i+=1){
arr[i].show();
}cout<<endl;
for(int i=0;i<3;i+=1){
array[i].show();
}
return 0;
}
例题:设计一个员工类(Employee),可以对所有员工加薪,并找出最高薪金员工。
#include<iostream>
#include<cstring>
using namespace std;
class Employee{
char ID[10];
char *ptr;
double s;
public:
Employee();
Employee(char id[],char *q,double ss);
char *getName();
double getS();
void growS(double add);
void display();
~Employee();
};
Employee::Employee(){
ptr=NULL;
}
Employee::Employee(char id[],char *q,double ss){
strcpy(ID,id);
ptr=new char [strlen(q)+1];
strcpy(ptr,q);
s=ss;
}
Employee::~Employee(){
delete []ptr;
}
char *Employee::getName(){
return ptr;
}
double Employee::getS(){
return s;
}
void Employee::growS(double d){
s+=d;
}
void Employee::display(){
cout<<ID<<":"<<ptr<<",salary: "<<s<<endl;
}
int main(){
Employee employee[3]={Employee("101","LK",2340),Employee("102","ZQ",3440),Employee("103","GF",4540)};
int i,maxz=0,cnt;
double temp;
cout<<"加薪前:"<<endl;
for(int i=0;i<3;i++){
employee[i].display();
}
cout<<"加薪后:"<<endl;
for(int i=0;i<3;i++){
employee[i].growS(600);
employee[i].display();
temp=employee[i].getS();
if(temp>maxz){
cnt=i;
maxz=temp;
}
}
cout<<"最高工资的人员是:"<<employee[cnt].getName()<<",工资额:"<<employee[cnt].getS()<<endl;
return 0;
}
指向对象的指针与对象的引用
定义:
#include<iostream>
using namespace std;
class A{
int i;
public:
A(int k=0){
i=k;
}
void display(){
cout<<"i="<<i<<endl;
}
};
int main(){
A a1,a2(5);
A *p=&a1;
p->display();
p=&a2;
p->display();
return 0;
}
例题:对于在函数赋值
(1)、形参为对象。
(2)、形参为对象的引用。
(3)、形参为对象指针。
其中第一种是行不通的。
#include<iostream>
using namespace std;
class A{
int i;
public:
A(){
i=0;
cout<<"调用了构造函数!!!\n";
}
A(const A & q){
i=q.i;
cout<<"调用了复制构造函数"<<endl;
}
void seti(int j){
i=j;
}
int get(){
return i;
}
void display(){
cout<<"i="<<i<<endl;
}
};
void fun1(A a, int x){
a.seti(x);
}
void fun2(A& r,int x){
r.seti(x);
}
void fun3(A *p,int x){
p->seti(x);
}
int main(){
A a;
cout<<"函数调用前:\n";
a.display();
cout<<"对象作为函数参数\n";
fun1(a,2);
a.display();
cout<<"对象引用作为函数参数\n";
fun2(a,2);
a.display();
cout<<"指针作为参数函数"<<endl;
fun3(&a,4);
a.display();
return 0;
}
this指针
例题5-14:设计长方形类,显式使用this指针
#include<iostream>
using namespace std;
class R{
int len,w;
public:
R(int len,int w);
int getArea();
};
R::R(int len,int w){
this->len=len;
this->w=w;
}
int R::getArea(){
return (this->len)*(this->w);
}
int main(){
R r1(2,5),r2(3,6);
cout<<"First Area is "<<r1.getArea()<<endl;
cout<<"Second Area is "<<r2.getArea()<<endl;
return 0;
}
对象的动态创建与销毁:
主要运用了两个形式:
New:
new ClassName(如:int);
有两种形式:
1、new A(8)
2、new A[3];
Delete:
1、delete A;
2、delete []A;
例题:
#include<iostream>
using namespace std;
class A{
int i;
public:
A(int k=0){
i=k;
}
void display(){
cout<<"i="<<i<<endl;
}
};
int main()
{
A *p=new A;
p->display();
delete p;
p=new A(8);
p->display();
delete p;
p=new A[3];
A *q=p;
for(int i=0;i<3;i++){
q++->display();
}
delete []p;
return 0;
}
例题5-15 设计点类,由用户决定点的数目及位置,将点展示在屏幕。
#include<iostream>
using namespace std;
class Point{
int x,y;
public:
Point(int a=0,int b=0){
x=a,y=b;
}
void setXY(int u,int v){
x=u,y=v;
}
void display(){
cout<<"("<<x<<','<<y<<")\t";
}
};
int main(){
Point *p , *q;
int num,i,x,y;
cout<<"Enter the number of points:";
cin>>num;
q=p=new Point[num];
for(int i=0;i<num;i++){
cout<<"Enter x:";
cin>>x;
cout<<"Enter y:";
cin>>y;
q->setXY(x,y);
q++;
}
q=p;
cout<<"共有"<<num<<"个点,其坐标是:\n";
for(i=0;i<num;i++){
q->display();
q++;
}
cout<<endl;
delete p;
return 0;
}
对象的引用:
例题(改名字):
#include<iostream>
using namespace std;
class Point {
int x,y;
public:
Point(int a=0,int b=0){
x=a,y=b;
}
void display(){
cout<<"("<<x<<','<<y<<")\n";
}
};
int main(){
Point p1(1,2);
Point &r=p1;
r.display();
return 0;
}
类的组合
组合的定义:
#include<iostream>
using namespace std;
class A;
class B;
class A{
int i;
public:
A(int k=0){
i=k;
cout<<"调用了构造函数.\n";
}
};
class B{
A a;
int j;
};
int main(){
B b;
return 0;
}
组合类的构造函数
例题:
#include<iostream>
using namespace std;
class Point{
double x,y;
public:
Point(double a=0,double b=0){
x=a;
y=b;
cout<<"调用了Point类的构造函数"<<endl;
}
Point(const Point &A){
cout<<"调用了Point类的复制构造函数"<<endl;
x=A.x;
y=A.y;
}
void show(){
cout<<"("<<x<<","<<y<<")"<<endl;
}
};
class Circle {
Point c;
double R;
public:
Circle(const Point &pt,double r):c(pt)
{
cout<<"调用了Circle类的构造函数"<<endl;
R=r;
}
void display(){
c.show();
}
};
int main()
{
Point P(1,2);
Circle C(P,3);
C.display();
return 0;
}
组合类的顺序:
成员对象的初始化顺序是按照对象成员在组合类中的声明的先后顺序进行,
与成员初始化表中成员对象出现的顺序无关。
例题:
#include<iostream>
using namespace std;
class A{
int i;
public:
A(int s=0){
i=s;
cout<<"A类的构造函数"<<endl;
}
A(A & ta){
i=ta.i;
cout<<"A类的复制构造函数"<<endl;
}
~A(){
cout<<"A类的析构函数"<<endl;
}
};
class B{
int j;
public:
B(int t=0){
j=t;
cout<<"B类的构造函数"<<endl;
}
B(B &tb){
j=tb.j;
cout<<"B类的复制函数"<<endl;
}
~B(){
cout<<"B类的析构函数"<<endl;
}
};
class C{
B b;
A a;
int k;
public:
C(int u,int v,int w):a(u),b(v),k(w){
cout<<"C类的构造函数"<<endl;
}
C(A &ta,B& tb,int w):a(ta),b(tb),k(w){
cout<<"C类复制函数"<<endl;
}
~C(){
cout<<"C类的析构函数"<<endl;
}
};
int main(){
{
C c1(2,5,6);
}
cout<<"首先生成成员函数,再创建复合对象\n";
A ta;
B tb(5);
C c2(ta,tb,2);
return 0;
}
string类:
s.length()和‘+’:
#include<iostream>
#include<string>
using namespace std;
int main()
{
string str1="we";
string str2=("programming");
cout<<"programming的长度是"<<str2.length()<<endl;
string str3;
str3=str1+" are "+str2;
cout<<str3<<endl;
return 0;
}
类的静态成员
例题,静态成员:
#include<iostream>
using namespace std;
class Point{
double x,y;
static int cnt;
public:
Point(double a=0,double b=0):x(a),y(b){
cnt++;
}
~Point(){
cnt--;
}
void show(){
cout<<"the number of Point is "<<cnt<<endl;
}
};
int Point::cnt=0;
int main(){
Point p1;
Point *p=new Point(1,2);
p->show();
delete p;
p1.show();
return 0;
}
静态函数成员:
#include<iostream>
#include<string>
#include<string.h>
using namespace std;
class Salesman{
char name[10];
int salecnt;
double price;
double per;
double com;
static int cnt;
static double tot;
public:
Salesman(char nm[],int Cnt,double Price,double Per){
strcpy(name,nm);
cnt=Cnt;
price=Price;
per=Per;
com=price*cnt*per;
tot+=com;
cnt++;
}static double getAver(){
return tot/cnt;
}static void show(){
cout<<"共有"<<cnt<<"名销售员,提成总额是"<<tot<<endl;
}
};
int Salesman::cnt=0;
double Salesman::tot=0.0;
int main(){
Salesman sman[]={
Salesman("Li",4,100,0.5),
Salesman("Wang",3,200,0.4),
Salesman("Liu",2,300,0.3)
};
Salesman::show();
cout<<"平均每人提成:"<<Salesman::getAver()<<endl;
return 0;
}
类的友元
友元函数:
例题5-19 用友元函数计算两点间的距离:
#include<iostream>
#include<cmath>
#include<string>
using namespace std;
class Point{
double x,y;
public:
Point(double a=0,double b=0){
x=a,y=b;
}
friend double dist(const Point &p1,const Point &p2);
};
double dist(const Point &p1,const Point &p2){
double d1,d2,dist;
d1=p1.x-p2.x;
d2=p1.y-p2.y;
dist=sqrt(d1*d1+d2*d2);
return dist;
}
int main(){
Point p1(1.0,2.0),p2(2.0,3.0);
cout<<"两点之间的距离是:"<<dist(p1,p2)<<endl;
return 0;
}
常对象:
例题:
#include<iostream>
using namespace std;
class Time{
int h,mi,sec;
public:
Time(int hr,int mnt,int scd){
h=hr;
mi=mnt;
sec=scd;
}
void setTime(int nh,int nm,int ns);
void show()const ;
};
void Time::setTime(int hr,int mn,int se){
h=hr;
mi=mn;
sec=se;
}
void Time::show()const {
cout<<h<<":"<<mi<<":"<<sec;
}
int main(){
Time t(12,11,15);
//t.setTime(12,10,15);
t.show();
return 0;
}
常函数:
#include<iostream>
using namespace std;
class A{
int ta;
public:
A(int tmp=12):ta(tmp){};
void hello ()const{
printf("hello");
}
void xA()const{
cout<<ta<<endl;
//changA();
hello();
}
void changA(){
ta=10;
xA();
}
};
int main(){
A ta(2);
ta.changA();
return 0;
}