C++基础语法二

一、类和对象
1.1面向对象编程介绍
使用类和对象来完成特定的功能的集合,通过每个对象来管理自己的数据和方法。
用到一个关键词:class
超强版的struct :类

1.2类和对象
1)c++中的类是class,可以看成是C语言中的struct的超强版本。结构体是一种构造类型,可以包含若干成员,类也一样,除了struct基本功能之外,类还有新增权限,
2)类的使用说明
1>类和struct一样,定义结尾需要加; 他是类的一部分,表示类定义结束,不能省略。
2>类也是一种构造类型,本身不占用内存空间,内存空间的计算方式和struct差不多。
3>对象成员的访问方式和struct一样,通过.或者->来访问。
4>类中的函数的作用范围由类来决定,作用范围可能是某个命名空间。

#include <iostream>
using namespace std;

struct Student   //结构体默认是共有的
{
    
    
    int age;
    char *name;
};

class Student1    //类默认是私有的
{
    
    
    public:   //共有权限
    int age;
    char *name;
    void print()
    {
    
    
        cout<<"age = "<<age<<"name = "<<name<<endl;
    }
};



int main(int argc,char const *argv[] )
{
    
    
    Student1 s1;
    s1.age = 19;
    s1.name = "xiaoming";
    s1.print();
    return 0;
}

1.3 访问控制
访问级别:共有权限(public),保护权限(protect),私有权限(private)。
public :共有属性, 凡是在它下面定义的属性或者方法,类的内部和外部都可以访问。
protect:保护属性,凡是在它下面定义的属性或者方法,类的内部和继承的内部可以访问,外部不可以访问。
private:私有属性,凡是在它下面定义的属性或者方法,类的内部可以访问,它的继承和外部都不可以访问。

#include <iostream>
using namespace std;

class Test
{
    
    
    public:          //公有属性,类的内部和外部都可以访问
        int b;
        void f2(){
    
    }
    protected:       //保护属性,类的内部和类的继承中访问
        int c;
        void f3(){
    
    }
    private:         //私有属性,类的内部可以访问
        int a;
        void f1(){
    
    }
};

int main(int argc, char const *argv[])
{
    
    
    Test t1;
    //t1.a = 1;   //私有成员无法在类的外部访问
    t1.b = 2;
    //t1.c = 3;

    return 0;
}
 **注意:1.public ,protected, private的关键词可以出现多次,有效范围是在下一个关键词出现之前
 			2.struct默认是公有属性,class默认是私有属性**
#include <iostream>
using namespace std;

class Circle
{
    
    
    private:
        int m_r;
        double m_s;
    
    public:
        void SetR(int r)    //用共有来操作私有属性
        {
    
    
            m_r = r;

        }
        double Gets()
        {
    
    
            m_s = 3.14 * m_r * m_r;
            return m_s;
        }
};

int main(int argc, char const *argv[])
{
    
    
    Circle c1;   //创建对象
    c1.SetR(2);              
    cout<<"面积 = "<<c1.Gets()<<endl;
    return 0;
}

1.4类的实际使用(分文件使用)
设计一个立方体类Cube,求出立方体的面积和体积,并判断两个立方体是否相等
要求:私有成员变量(属性):长length,宽wide, 高hight
成员函数(方法):求面积和体积
全局函数:判断两个立方体是否相等

//头文件

#ifndef _CUBE_H_
#define _CUBE_H_
#include <iostream>

using namespace std;

class Cube
{
    
    
    private:
        int m_length;
        int m_wide;
        int m_hight;
    public:
        int GetS();   //得到面积
        int GetV();   //得到体积
        void SetS(int length,int wide,int hight);  //设置长宽高
        void SetV(int length,int wide,int hight);
        
        int Getlength();
        int GetWide();
        int Gethight();
};

bool CubeIsEqu(Cube c1, Cube c2);     //判断是否相等

#endif
#include "Cube.h"

//功能实现
void Cube::SetS(int length, int wide, int hight)
{
    
    
    m_length = length;
    m_wide = wide;
    m_hight = hight;
}

void Cube::SetV(int length, int wide, int hight)
{
    
    
    m_length = length;
    m_wide = wide;
    m_hight = hight;
}

int Cube::GetS()
{
    
    
    return m_length * m_wide * m_hight;
}

int Cube::GetV()
{
    
    
    return (2 *(m_length * m_wide + m_length * m_hight + m_wide * m_hight));
}

int Cube::Getlength()
{
    
    
    return m_length;
}

int Cube::GetWide()
{
    
    
    return m_wide;
}

int Cube::Gethight()
{
    
    
    return m_hight;
}

bool CubeIsEqu(Cube c1, Cube c2)
{
    
    
    if(c1.Getlength() == c2.Getlength() && c1.GetWide() == c2.GetWide() && c1.Gethight() == c2.Gethight())
    {
    
    
        return true;
    }
    else
    {
    
    
        return false;
    }
}
#include "Cube.h"

int main(int argc, char const *argv[])
{
    
    
    Cube c1;
    Cube c2;

    c1.SetS(3,4,5);
    c2.SetS(3,5,4);

    cout<<"c1面积 = "<<c1.GetS()<<endl;
    cout<<"c2面积 = "<<c2.GetS()<<endl;

    cout<<"c1体积 = "<<c1.GetV()<<endl;
    cout<<"c2体积 = "<<c2.GetV()<<endl;

    if(CubeIsEqu(c1,c2))
    {
    
    
        cout<<"c1 = c2"<<endl;
    }
    else
    {
    
    
        cout<<"c1 != c2"<<endl;
    }

    return 0;
}

在这里插入图片描述
练习:面向对象编程实例
要求:设计一个圆形类和一个点类,计算点在员外还是圆内,即求点和圆的关系
1)点:属性: 横坐标和纵坐标
方法:点和点之间的距离计算
2)圆:属性:圆心,半径
方法:1.设计圆心和半径
2.判断点和园的关系

#ifndef CIRCLE_H_
#define CIRCLE_H_

#include <iostream>
using namespace std;

class Point  //点
{
    
    
    private:
        int m_x;
        int m_y;  //横纵坐标
    public:
        void SetXY(int x,int y);    //输入点的坐标
        int Distance(Point &p);   //距离
        int GetX();
        int GetY();
};

class Circle  //圆
{
    
    
    private:
        int m_r;   //半径
        Point m_center;  //圆心
    public:
        void SetC(int x, int y, int m_r);
        bool judge(Point &p);
        
       
};

//bool Circle::judge(Point &p);

#endif
#include "circle.h"

void Point::SetXY(int x, int y)
{
    
    
    m_x = x;
    m_y = y;
}

int Point::GetX()
{
    
    
    return m_x;
}

int Point::GetY()
{
    
    
    return m_y;
}

void Circle::SetC(int x,int y,int m)
{
    
    
    m_center.SetXY(x,y);  
    m_r = m;   //半径

}

int Point::Distance(Point &p)
{
    
    
    int dis = (p.GetX() - m_x) * (p.GetX() -m_x) + (p.GetY() - m_y) * (p.GetY() - m_y);
    return dis;
}

bool Circle::judge(Point &p)
{
    
    
    if(p.Distance(m_center) <= m_r * m_r)
    {
    
    
        return true;
    }
    else
    {
    
    
        return false; 
    }

}
#include "circle.h"

int main(int argc, char const *argv[])
{
    
    
    Point p1;
    p1.SetXY(0,0);
    Circle c1;
    c1.SetC(0,0,1);
    if(c1.judge(p1))
    {
    
    
        cout<<"点在圆内或者圆上"<<endl;
    }
    else
    {
    
    
        cout<<"点在园外"<<endl;
    }

    return 0;
}

在这里插入图片描述

1.5 对象的构造和析构
1)构造函数:是C++中一种特殊的成员函数,它的名字和类名相同,没有返回值,不需要用户显示调用,而是在创建对象的时候自动执行,这种特殊的函数称为构造函数。
注意:1.构造函数名必须与类同名。2.构造函数不能有返回值。 3.构造函数在定义的时候自动调用,不需要手动调用。

#include <iostream>

using namespace std;

class Array
{
    
    
    private:
        int *data;  //数组的起始地址
        int size;   //数组大小
    public:
        Array();  //无参构造函数,函数名和类名一样,没有返回值,完成对象的初始化操作
        void SetVal(int Index,int val);
        int GetVal(int Index);
        ~Array();  //析构函数
};

Array ::Array() //无参构造函数,函数名和类名一样,没有返回值,完成对象的初始化操作
{
    
    
    cout<<"array的无参构造函数"<<endl;
    size = 5;
    data = (int *)malloc(sizeof(int)*size);
}

void Array::SetVal(int Index,int val)
{
    
    
    data[Index] = val;
}

int Array::GetVal(int Index)
{
    
    
    return data[Index];
}

Array::~Array()
{
    
    
    cout<<"Array的析构函数"<<endl;
    if(data != NULL)
    {
    
    
        free(data);
    }
}

int main(int argc,char const *argv[])
{
    
    
    Array a1;
    for(int i = 0; i < 5; i++)
    {
    
    
        a1.SetVal(i,i+1);

    }
    for(int i = 0; i < 5; i++)
    {
    
    
        cout<<a1.GetVal(i)<<" ";
    }

    cout<<endl;

    return 0;
}

在这里插入图片描述
2.构造函数的重载和调用
和普通函数一样,构造函数也是允许重载的,也就是说,一个类可以有多个构造函数,在创建对象时根据传递的实参来判断调用哪一个函数

#include <iostream>

using namespace std;

class Array
{
    
    
    private:
        int *data;  //数组的起始地址
        int size;   //数组大小
    public:
        Array();  //无参构造函数,函数名和类名一样,没有返回值,完成对象的初始化操作
        Array(int s);  //有参构造函数
        Array(int s,int z);  //有两个参数的构造函数
        Array(const Array &a);
        void SetVal(int Index,int val);
        int GetVal(int Index);
        ~Array();  //析构函数
};

Array::Array(int s)  //有参构造函数
{
    
    
    cout<<"size = "<<s<<endl;
    size = s;
    data = (int *)malloc(sizeof(int) * size);
    cout<<"有一个参数的构造函数"<<endl;
}

Array::Array(int s,int z)  //有两个参数的构造函数
{
    
    
    size = s;
    data = (int *)malloc(sizeof(int) * size);
    cout<<"有一个参数的构造函数"<<endl;
}

Array::Array(const Array &a)
{
    
    
    cout<<"Array的拷贝构造函数"<<endl;
}

Array ::Array() //无参构造函数,函数名和类名一样,没有返回值,完成对象的初始化操作
{
    
    
    cout<<"array的无参构造函数"<<endl;
    size = 5;
    data = (int *)malloc(sizeof(int)*size);
}

void Array::SetVal(int Index,int val)
{
    
    
    data[Index] = val;
}

int Array::GetVal(int Index)
{
    
    
    return data[Index];
}

Array::~Array()
{
    
    
    cout<<"Array的析构函数"<<endl;
    if(data != NULL)
    {
    
    
        free(data);
    }
}

int main(int argc,char const *argv[])
{
    
    
    Array a1;
    for(int i = 0; i < 5; i++)
    {
    
    
        a1.SetVal(i,i+1);

    }
    for(int i = 0; i < 5; i++)
    {
    
    
        cout<<a1.GetVal(i)<<" ";
    }

    cout<<endl;

    cout<<"***************"<<endl;
   
    Array a2 = 10;
    for(int i = 0; i < 10; i++)
    {
    
    
        a2.SetVal(i,i+100);

    }
    for(int i = 0; i < 10; i++)
    {
    
    
        cout<<a2.GetVal(i)<<" ";
    }

    cout<<endl;

    cout<<"***************"<<endl;

    Array a3(10,8);
    Array a4(a1);

    return 0;
}


在这里插入图片描述
3.拷贝构造函数的调用时机
1)用一个对象初始化另一个对象的时候
2)当函数的参数是一个类的对象
3)当函数返回一个对象的引用

#include <iostream>

using namespace std;

class Array
{
    
    
    private:
        int *data;  //数组的起始地址
        int size;   //数组大小
    public:
        Array();  //无参构造函数,函数名和类名一样,没有返回值,完成对象的初始化操作
        Array(const Array &a);
        void SetVal(int Index,int val);
        int GetVal(int Index);
        ~Array();  //析构函数
};

Array::Array(const Array &a)
{
    
    
    cout<<"Array的拷贝构造函数"<<endl;
}

Array ::Array() //无参构造函数,函数名和类名一样,没有返回值,完成对象的初始化操作
{
    
    
    cout<<"array的无参构造函数"<<endl;
    size = 5;
    data = (int *)malloc(sizeof(int)*size);
}

void Array::SetVal(int Index,int val)
{
    
    
    data[Index] = val;
}

int Array::GetVal(int Index)
{
    
    
    return data[Index];
}

Array::~Array()
{
    
    
    cout<<"Array的析构函数"<<endl;
    if(data != NULL)
    {
    
    
        free(data);
    }
}

void print(Array a)   //当函数的形参是一个对象 array a = a1;
{
    
    
    a.GetVal(1);
}

Array& fun()  //函数返回值是一个对象
{
    
    
    Array a1;
    return a1;
}

int main(int argc,char const *argv[])
{
    
    
    Array a1;
    for(int i = 0; i < 5; i++)
    {
    
    
        a1.SetVal(i,i+1);

    }
    for(int i = 0; i < 5; i++)
    {
    
    
        cout<<a1.GetVal(i)<<" ";
    }

    cout<<endl;

    cout<<"***************"<<endl;
   
    Array a2 = fun();
  
    return 0;
}


在这里插入图片描述

4.深拷贝
在这里插入图片描述

#include <iostream>

using namespace std;

class Array
{
    
    
    private:
        int *data;  //数组的起始地址
        int size;   //数组大小
    public:
        Array();  //无参构造函数,函数名和类名一样,没有返回值,完成对象的初始化操作
        Array(const Array &a);
        void SetVal(int Index,int val);
        int GetVal(int Index);
        ~Array();  //析构函数
};

Array::Array(const Array &a)   //深拷贝
{
    
    
    cout<<"Array的拷贝构造函数"<<endl;
    size = a.size;
    data =(int *)malloc(sizeof(int) * size);
    for(int i = 0; i < size; i++)
    {
    
    
        data[i] = a.data[i];
    }
}

Array ::Array() //无参构造函数,函数名和类名一样,没有返回值,完成对象的初始化操作
{
    
    
    cout<<"array的无参构造函数"<<endl;
    size = 5;
    data = (int *)malloc(sizeof(int)*size);
}

void Array::SetVal(int Index,int val)
{
    
    
    data[Index] = val;
}

int Array::GetVal(int Index)
{
    
    
    return data[Index];
}

Array::~Array()
{
    
    
    cout<<"Array的析构函数"<<endl;
    if(data != NULL)
    {
    
    
        free(data);
    }
}

void print(Array a)   //当函数的形参是一个对象 array a = a1;
{
    
    
    a.GetVal(1);
}


int main(int argc,char const *argv[])
{
    
    
    Array a1;
    for(int i = 0; i < 5; i++)
    {
    
    
        a1.SetVal(i,i+1);

    }
    for(int i = 0; i < 5; i++)
    {
    
    
        cout<<a1.GetVal(i)<<" ";
    }

    cout<<endl;

    cout<<"***************"<<endl;
   
    Array a2(a1);  //用一个对象初始化另一个对象
  
    return 0;
}



在这里插入图片描述
1.7 析构函数
析构函数会在对象销毁时自动调用,析构函数没有返回值,没有参数,不能重载。
1)匿名对象


```cpp
#include <iostream>
using namespace std;

class Demo
{
    
    
    public:
        Demo()
        {
    
    
            cout<<"Demo的无参构造函数"<<endl;
        }
        ~Demo()
        {
    
    
            cout<<"Demo的析构函数"<<endl;
        }
};

int main(int argc, char const *argv[])
{
    
    
    Demo();  //匿名对象,本行执行完立即被释放
    Demo();
    
    cout<<"*******************"<<endl;
    return 0;
}

1)C++中malloc 和 new 使用

```cpp
#include <iostream>
using namespace std;

class Demo
{
    public:
        Demo()
        {
            cout<<"Demo的无参构造函数"<<endl;
        }
        Demo(int a, int b)
        {
            cout<<"Demo的两个参数的构造函数"<<endl;
        }

        ~Demo()
        {
            cout<<"Demo的析构函数"<<endl;
        }
};

int main(int argc, char const *argv[])
{
    Demo *pd = (Demo *)malloc(sizeof(Demo)); //在堆空间申请对象那个,malloc不会自动调用构造和析构函数
    if(pd == NULL)
    {
        cout<<"malloc failed"<<endl;
    }
    free(pd);

    Demo *pd2 = new Demo; //申请堆空间,自动调用构造函数
    delete pd2;  //释放空间,自动调用析构函数

    Demo *pd3 = new Demo(100,200);
    delete pd3;
    
    return 0;
}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_43296982/article/details/123787290
今日推荐