复习三—类和对象

类和对象
1.类是对象的抽象,对象是类的实例化。结构体里面只有数据成员,类里面有数据成员和成员函数。
类所定义的是一个标准,不分配内存空间
2.访问属性,public,protected,private
3.函数声明时有分号,定义的格式如下:
(1) 将成员函数在类外定义的一般形式是: 
 返回类型 类名∷成员函数名(参数表) 
 { 
 // 函数体 
 }
(2) 将成员函数以内联函数的形式进
行说明。在C++中,可以用下面两种格式
将成员函数声明为类的内联函数: 
 
 a.隐式声明 直接将函数声明在类外部
 b.显式声明内联函数 
这种成员函数在类外定义的一般形式是: 
inline 返回类型 类名::成员函数名(参数表)
 { 
 // 函数体 
}
 内联函数作用:以空间换时间,提高运行速度
4.成员函数的重载(返回值类型不作为重载标志),(函数名相同,参数类型,个数不同),类名相同的成员函数才能成为重载成员函数
5.对象的定义(与结构体类似)
(1)在声明类的同时,直接定义对象,即在声明类的右花
括号“}”后,直接写出属于该类的对象名表。
(2)声明了类之后,在使用时再定义对象,定义的
格式与一般变量的定义格式相同
6.对象成员的访问:
 通过成员运算符“.”访问
 通过对象的指针访问“”

int main()
{
   student stu,*p;
   p=&stu;
   p->set(2);
   (*p).get();
}


 通过对象的引用变量访问对象中的数据成员
例题:定义一个point类
要求:
数据成员:x,y
成员函数:
 设置x的值、设置y的值,获取x的值,获取y的值
 计算两个点之间的距离
编写主函数进行测试

#include <iostream>
#include <cmath>
using namespace std;
class Point{
int x,y;
public:
void setx(int x) { this->x=x; }
void sety(int y) { this->y=y; }
int getx() { return x; }
int gety() { return y; }
double distance(Point p2) {return sqrt((x-p2.x)*(x-p2.x)+(y-p2.y)*(y-p2.y));}
};
int main(){
int x1,y1,x2,y2;
Point p1,p2;
cout<<"Please input Point1:"; cin>>x1>>y1;
cout<<"Please input Point2:"; cin>>x2>>y2;
p1.setx(x1); p1.sety(y1); p2.setx(x2); p2.sety(y2);
cout<<p1.distance(p2)<<endl; cout<<p2.distance(p1)<<endl;
return 0;
}

7.this指针
需要显式引用this指针的三种情况
(1)在类的非静态成员函数中返回类对象本身或对
象的引用的时候,直接使用 return *this,返回本
对象的地址时,return this。 
(2)当参数与成员变量名相同时,如this->x = x,
不能写成x = x。 
(3)避免对同一对象进行赋值操作,判断两个对象
是否相同时,使用this指针
void add(int i)与void add(int i,A*const this),每个函数都有this指针,会隐藏不写。

8.构造函数
(1)定义格式
类名::类名([参数表])
{
 函数语句
}
(若显式的定义构造函数,系统默认的无参构造会消失)
(2)利用构造函数创建对象有两种格式
a. 利用构造函数直接创建对象.其一般形式为:
 类名 对象名[(实参表)];
 这里的“类名”与构造函数名相同,“实
参表”是为构造函数提供的实际参数。
b.利用构造函数创建对象时,通过指针和new来实现。其一般语法形式为:
 类名 *指针变量 = new 类名[(实参表)];
例如:
 Date *date1=new Date(1998,4,28);
就创建了对象(*date1)

例:
  

 void main()
{
 Date *date1;
 date1=new Date(1998,4,28); 
// 以上两条语句可合写成:Date *date1=new Date(1998,4,28);
 cout<<"Date1 output1:"<<endl;
 date1showDate(); 
 date1  setDate(2002,11,14);
 cout<<"Date1 output2:"<<endl;
 date1  showDate(); 
 delete date1; }

(3).必须使用参数初始化列表对数据成员进行初始化的几种情况
• 数据成员为常量
• 数据成员为引用类型
• 数据成员为没有无参构造函数的类的对象
按照数据成员在类中的声明顺序进行初始化,与初
始化成员列表中出现的顺序无关

(4)构造函数的重载(定义了全部带默认值的构造函数,不能再定义无参构造函数)
(带默认值的构造函数相当于多个构造函数)

9.析构函数

析构函数自动调用(隐式调用)
析构函数没有返回值,不能有参数,也不能重载,一个类只能定义一个析构函数
定义格式如下:
类名::~类名()
{
 函数语句
}
默认析构函数形式如下:
类名::~类名(){}
必须定义析构函数的情况:
但如果类的数据成员中包含指针变量是从堆上进行存储空
间分配的话,需要在析构函数中进行存储空间的回收

10.复制构造函数
复制构造函数名与类名相同,并且也没有返回值类型。
复制构造函数可写在类中,也可以写在类外。
复制构造函数有且仅有一个参数,即是同类对象的引用。
如果没有显式定义复制构造函数,系统自动生成一个默认形式的复制构造函数
定义格式:
class 类名
{
public:
 类名(参数表); //构造函数
 类名([const] 类名 &对象名); //复制构造函数
 ┇ };
类名::类名([const] 类名 &对象名) {
 函数语句
}
以下三种情况下由编译系统自动调用复制构造:
a.声明语句中用类的一个已知对象初始化该类的另一个对象时。
b.当对象作为一个函数实参传递给函数的形参时,需要将实参
对象去初始化形参对象时,需要调用复制构造函数。
c.当对象是函数的返回值时,由于需要生成一个临时对象作为
函数返回结果,系统需要将临时对象的值初始化另一个对象,
需要调用复制构造函数。


浅复制与深复制:
在用一个对象初始化另一个对象时,只复制了数据成员,而没有复制资源,使两个对象同时指向了同一资源的复制方式称为浅复制。
默认复制构造函数所进行的是简单数据复制,即浅复制
通过一个对象初始化另一个对象时,不仅复制了数据成员,也复制了资源的复制方式称为深复制。
缺省复制构造函数所进行的复制是浅复制。
当成员变量中含有指针变量时,需要定义深复制构造函数

深复制构造函数示例
 

Person::Person(const Person& P0) //复制构造函数的实现
{
 name=new char[strlen(P0.name)+1];
strcpy(name,P0.name);
age=P0.age;
salary=P0.salary;
}

10.静态成员:(只被初始化一次,生命期长)
静态成员提供了同一个类不同对象数据成员的共享机制
例如:
 static int total;
 static void display();
静态成员函数可以直接访问该类的静态数据成员,而不
能直接访问非静态数据成员。

例:

#include<iostream>
#include<cstring>
using namespace std;
class Person
{
static int total;
static int Max_number;
public:
Person();
static void display()
{
cout<<"total="<<total<<endl;
 cout<<"Max_number:"<<Max_number<<endl;
}
void print_no()
{
cout<<S_number<<endl;
}
private:
char *name;
int S_number;
};

Person::Person()
{
 char name1[20];
cout<<"Please Input Staffer Name:";
cin>>name1;
name=new char[strlen(name1)+1];
strcpy(name,name1);
total++;
S_number=1000+total; //员工编号从1000开始
Max_number=S_number;
}
int Person::total=0;
int Person::Max_number=0;
void main()
{
Person s1;
Person s2;
 Person s3;
Person s4;
 Person::display(); //通过类名调用静态成员函数
s4.display(); //通过对象调用静态成员函数
s3.print_no(); //输出第3位员工的个人编号
}

11.友元
若需要在类的外部直接访问类的私有数据成员,在C++中,通过定义友元可以实现这一功能
友元的作用:共享
性质:单向性、非传递性
格式:friend 返回值类型 函数名(参数表);
友元函数可以访问类中的私有数据成员,但友元函数不是类的成员函数;
友元函数可以是一个普通函数,也可以是另外一个类的成员函数;
友元类:若一个类被声明为另一个类的友元,则该类的所有成员函数都是另一个类的友元。
友元类的格式:friend class 类名;

12:常类型
常类型是指使用关键字const说明的类型,常类型的变量或对象成员的值在程序运行期间是不可改变的
常引用的说明形式如下:
const 类型说明符 &引用名;
常对象的说明格式
类名 const 对象名;或:
const 类名 对象名;

13,类的包含
 类的包含(称为has A)是程序设计中一种软件重用技术。即定义一个新的类时,通过编译器把另一个类 “抄”进来。
//例6-23 简单对象成员初始化
 

#include<iostream>
using namespace std;
class A
{ public:
 A(int x):a(x){ }
 int a ;
};
class B
{ public:
 B( int x, int y ) : aa(x) { b = y ; }
 void out() { cout<<"aa = "<<aa.a<<endl<<"b = "<<b<<endl ; }
 private:
 int b ;
 A aa ;
} ;
int main()
{ B objB( 3, 5 ) ;
 objB.out() ;
}


题目整理:
一:
定义一个dog类,包含age、weight属性,以及对这些属性
的操作方法。实现并测试这个类。

复习时做的:

#include<iostream>
using namespace std;
class dog
{
private:
    int age;
    double weight;
public:
    dog(){};
    dog (int a,double w)
    {
        age=a;
        weight=w;
    }
   void get()
    {
        cout<<"该小狗的年龄为:"<<age<<"体重为:"<<weight<<endl;
    }
    void reset()
    {
        cout<<"请输入小狗现在的年龄和体重"<<endl;
        cin>>age>>weight;
    }
};
int main()
{
    dog d1(2,20.0);
    d1.get();
    d1.reset();
    d1.get();
    return 0;
}


学习时做的:

#include <iostream>
using namespace std;
class dog
{
private:
double age;
double weight;
public:
dog(){};
~dog(){}
dog(double m,double n):age(m),weight(n){};
void setage(double age);
void setweight(double weight);
double showage();
double showweight();
};
inline void dog::setage(double age)
{
this->age=age;
}
inline void dog::setweight(double weight)
{
this->weight=weight;
}
inline double dog::showage()
{
return age;
}
inline double dog::showweight()
{
return weight;
}
int main()
{
double m,n;
cin>>m>>n;
dog a,b(17,20);
a.setage(m);
a.setweight(n);
cout<<"before:"<<endl;
cout<<a.showage()<<" "<<a.showweight()<<endl;
cout<<"now:";
cout<<b.showage()<<" "<<b.showweight()<<endl;
}


感觉之前做的好麻烦,应该是为了把学的东西都用一下吧(还是现在退步厉害)
二:
设计并测试一个名为Rectangle 的矩形类,其属性为矩形
的左下角与右上角两个点的坐标,能计算矩形的面积。
现在的:

#include <iostream>
using namespace std;
class Rectangle
{
private:
    double x1,y1,x2,y2;
public:
    Rectangle (){};
    Rectangle (double a,double b,double c,double d)
    {
        x1=a;y1=b;
        x2=c;y2=d;
    }
    void setleftdown()
    {
        cout<<"输入矩形左下角坐标"<<endl;
        cin>>x1>>y1;
    }
    void setrightup()
    {
        cout<<"输入矩形右上角坐标"<<endl;
         cin>>x2>>y2;
    }
    void area()
    {
        double x,y;
        x=x2-x1;
        y=y2-y1;
       cout<<1.0*x*y<<endl;
    }
} ;
int main()
{
    Rectangle a(1,2,2,4);
    a.area();
    Rectangle b;
    b.setleftdown();
    b.setrightup();
    b.area();
    return 0;
}


之前的:
 

#include <iostream>
using namespace std;
class cube
{
private:
    double x1,y1,x2,y2;
public:
    cube();
    ~cube();
    cube(double a,double b,double c,double d);
    void setleftup();
    void setrightdown();
    void showleftup();
    void showrightdown();
    double lalculatedarea();
};
inline cube::cube()
{}
inline cube::~cube()
{}
inline void cube::setleftup()
{
    cout<<"输入矩形左上角坐标"<<endl;
    cin>>x1>>y1;
}
inline void cube::setrightdown()
{
    cout<<"输入矩形右下角坐标"<<endl;
    cin>>x2>>y2;
}
double cube::lalculatedarea()
{
    double x=x1-x2,y=y1-y2;
    return x*y;
}
int main()
{
    cube a;
    a.setleftup();
    a.setrightdown();
  cout<<a.lalculatedarea()<<endl;
}

三:
创建一个Student类,该类中具有学生姓名,学号,性别,
年龄,三科成绩、平均成绩等数据成员。在该类中定义成
员函数实现相关信息的输入、输出。函数的原型声明放在
类定义中。实现并测试这个类。
A:
 

#include <iostream>
#include<cstring>
using namespace std;
class student
{
private:
    char *name;
    char *num;
    char sex;
    int age;
    double score1,score2,score3;
    double avescore;
public:
    student(){};
    student(char* name1,char* num1,double ag,char s,double a,double b,double c)
    {
        name=new char[strlen(name1)+1];
        strcpy(name,name1);
        num=new char[strlen(num1+1)+1];
        strcpy(num,num1);
        sex=s;
        age=ag;
        score1=a;score2=b;score3=c;
    }
    ~student(){};
    void setinformation()
    {
        cin>>name>>num>>age>>sex>>score1>>score2>>score3;
    }
    void showinformation()
    {
         cout<<"姓名:"<<name<<endl;
         cout<<" 学号:"<<num<<endl;
         cout<<" 年龄:"<<age<<endl;
         cout<<" 性别:"<<sex<<endl;
         cout<<" 学科1分数:"<<score1<<" 2:"<<score2<<" 3:"<<score3<<endl;
         cout<<" 三科平均成绩:"<<avescore<<endl;
   }
   void ave()
   {
        avescore=(score1+score2+score3)/3.0;
   }
};
int main()
{
    student n("zhang","123",18,'m',100,98,97);
    n.ave();
    n.showinformation();
    return 0;
}

B;

#include <iostream>
#include <cstring>
using namespace std;
class student
{
private:
    string name,number;
    double score1,score2,score3,age,ave;
    char genger;
public:
    student(){};
    student(string name,string number,double a,double b,double c,double age,char x);
    void setinformation();
    void showinformation();
    void ff();
};
student::student(string name,string number,double a,double b,double c,double age,char x)
{
    this->name=name,(*this).number=number,score1=a,score2=b,score3=c,this->age=age,genger=x;
}
void student::setinformation()
{
    cin>>name>>number>>score1>>score2>>score3>>age>>genger;
}
void student::showinformation()
{
    cout<<"姓名:"<<name<<endl;
    cout<<" 学号:"<<number<<endl;
    cout<<" 学科1分数:"<<score1<<" 2:"<<score2<<" 3:"<<score3<<endl;
    cout<<" 三科平均成绩:"<<ave<<endl;
    cout<<" 年龄:"<<age<<endl;
    cout<<" 性别:"<<genger<<endl;

}
void student::ff()
{
    ave=(score1+score2+score3)/3;
}
int main()
{
    student m;
    cout<<"请输入姓名 学号 学科1分数 学科2分数 学科3分数 年龄 性别"<<endl;
    m.setinformation();
    m.ff();
    m.showinformation();
}

四:
(1)定义一个point 类
数据成员:点的坐标x,y
成员函数:带默认值的构造函数、set函数(设置x,y的值)、 
                       输出x,y
(2)定义一个line类
 数据成员:线上的两个点point1,point2(用定义好的point类)
 成员函数:定义一条直线、计算线段的长度
(3)创建主函数,测试以上内容

#include <iostream>
#include<cmath>
#include<iomanip>
using namespace std;

class point {
public:
    double x, y;
public:
    point(double x = 0.0, double y = 0.0) : x(x), y(y) {}
    ~point() {}
    void set(double a,double b)
    {
        this->x=a;
        this->y=b;
    }
    double getX() { return x; }
    double getY() { return y; }
};
class line
{
private :
    point a,b;
public:
    void setline(point m,point n)
    {
        this->a=m;
       this->b=n;
    }
    void show()
    {
        cout<<"所求直线为("<<a.getX()<<","<<a.getY()<<")to("<<b.getX()<<","<<b.getY()<<")"<<endl;
    }
    double setdis()
     {
        double q=(a.x-b.x)*(a.x-b.x);
        double w=(a.y-b.y)*(a.y-b.y);
        double l=q+w;
        double h=sqrt(l);
        return h;
     }
};
int main()
{
    point class1,class2;
    line line1;
    class1.set(3,4);
    class1.getX();
    class1.getY();
    class2.set(0,0);
    class2.getX();
    class2.getY();
    line1.setline(class1,class2);
    line1.show();
    double m=line1.setdis();
    cout<<"线段长度为"<<m<<endl;
return 0;

}

用类包含求计算两点之间的距离

#include<cmath>
#include<iostream>
using namespace std;
class Point
{ public:
 Point( int xi=0, int yi=0 ) { x = xi; y = yi; }
 int GetX() { return x; }
 int GetY() { return y; }
 private: int x; int y;
};
class Distance
{ public:
 Distance( Point xp1, Point xp2 );
 double GetDis() { return dist; }
 private:
 Point p1, p2; //Point类数据成员
 double dist; //记录距离的数据成员
};
Distance::Distance( Point xp1, Point xp2 ) : p1( xp1 ), p2( xp2 )
{ double x = double(p1.GetX() - p2.GetX());
 double y = double(p1.GetY() - p2.GetY());
 dist = sqrt(x * x + y * y);
}
int main()
{ Point mp1( 5, 10 ), mp2( 20, 30 ) ;
 Distance mdist( mp1, mp2 ) ;
 cout<<"The distance is "<<mdist.GetDis()<<endl;
}

五:
创建一个Student类,该类中具有学生姓名(采用字符指针),学号,性别,年龄,三科成绩、平均成绩等数据成员。在该类中定义成员函数实现相关信息的输入、输出、平均成绩计算。
要求:
1、显式定义构造函数、析构函数、复制构造函数
2、创建主函数实现并测试这个类。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
class Student
{
    char *name;
    int num;
    char a;//性别
    int age;
    double score1,score2,score3;
    double ave;
public:
    Student(){};
    Student(const Student &p);
    void set();
    void show()
    {
       cout<<"姓名:"<<name<<endl;
       cout<<" 学号:"<<num<<endl;
       cout<<" 学科1分数:"<<score1<<" 2:"<<score2<<" 3:"<<score3<<endl;
       cout<<" 三科平均成绩:"<<ave<<endl;
       cout<<" 年龄:"<<age<<endl;
       cout<<" 性别:"<<a<<endl;
       }
    void countave()
    {
        ave=(score1+score2+score3)/3.0;
    }
    ~Student()
    {
        cout<<"Destructor"<<endl;
        delete[] name;
    }
};
void Student::set()
{
        char name1[30],aa;
        int n1,n2;
        double ac1,ac2,ac3;
        cin>>name1>>n1>>aa>>n2>>ac1>>ac2>>ac3;
        name=new char[strlen(name1)+1];
        strcpy(name,name1);
        num=n1,a=aa,age=n2,score1=ac1,score2=ac2,score3=ac3;
}
Student::Student(const Student &p)
{
    cout<<"copy"<<endl;
    name=new char[strlen(p.name)+1];
    strcpy(name,p.name);
    num=p.num,a=p.a,age=p.age,score1=p.score1,score2=p.score2,score3=p.score3,ave=p.ave;
}
int main()
{
    cout<<"请输入姓名 学号 学科1分数 学科2分数 学科3分数 年龄 性别"<<endl;
    Student T1;
    T1.countave();
    T1.set();
    T1.show();
    Student T2(T1);//因为平均成绩要计算所以没有一开始检测复制构造,计算完后把所有信息一次性copy过去;
    T2.show();
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

季沐晴

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值