C++第二课(类和对象)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/hu_junhua/article/details/86620596

1.面向对象编程的特点:

抽象:抽象 是人们认识事物的一种方法,抽象的关键是抓住事物的本质,而不是内部具体细节或具体实现。

封装:封装是按照信息屏蔽的原则,把对象的属性和操作结合在一起,构成一个独立的对象,通过限制属性和操作的访问权限,可以将属性隐藏在对象内部,对外提供一定的接口,在对象之外只能通过接口对对象进行操作,封装增强了对象的独立性,从而保证了数据的可靠性,外部对象不能直接操作对象的属性,只能使用对象提供的服务。

继承:继承表达了对象的一般与特殊的关系,特殊类的对象具有一般类的全部属性和服务。定义了一个类之后,又需要定义一个新类,这个新类与原来的类相比,如果只是增加或修改了部分属性和操作,这时可以用原来的类派生出新类,只需在新类中描述自己所特有的属性和操作即可,继承性大大简化了对问题的描述,提高了程序的可重用性,从而提高了程序设计,修改和扩充的效率。

多态:多态性是指同一个消息被不同对象接收时,产生不同结果,即实现同一接口,不同方法,在一般类中定义的属性和服务,如果在特殊类中不改变其名字,通过各自不同的实现后,可以居于不同的数据类型或具有不同的行为。

2.类的封装:

#include <iostream>

using namespace std;

class Circle //class就相当与结构体,但是里面可以包含成员函数
{
private:     //私有成员变量,只能在类中访问
    int m_r;

public:     //public公有属性,在类的内部和类的外部都可以使用,成员函数
    void setR(int r)
    {
        m_r= r;
    }
    
    double getS()
    {
        return 3.14 * m_r * m_r;
    }
};

int main()
{
    Circle c;//创建对象
    c.setR(10);
    cout << c.getS() << endl;
    return 0;
}

// C++中提供一个新的关键字 class, 用来定义类,使用方式和struct基本相同
// 但是增加一些其他的特性
// 类的封装:1、封装属性 2、封装方法
// 类的内部、类的外部
// 类的访问控制关键字:对属性和方法的使用权限进行限制
// public  : 可以在类的内部和类的外部访问
// private : 可以在类的内部但不能在类的外部访问
// protect :可以在类的内部访问,但不能在类的外部访问,用在继承里面

3.class与struct的区别

在用struct定义类时,所有成员的默认属性为public
在用class定义类时,所有成员的默认属性为private

4.类的声明与类的实现分开:即成员函数只写成员函数的声明,函数的具体实现在另一个文件中实现

1.圆的面积:

Circle.h:

#ifndef CIRCLE_HH
#define CIRCLE_HH

class Circle
{
private:
    int m_r;
public:     //声明类的成员函数,函数在其他地方实现
    void setR(int r);
    double getS();
};

#endif


Circle.cpp

#include <iostream>
#include "Circle.h"

using namespace std;

void Circle::setR(int r)
{
    m_r = r;
}


double Circlr::getS()
{
    return 3.14 * m_r * m_r; 
}

main.cpp

#include <iostream>
#include "Circle.h"

using namespace std;

int main()
{
    Circle c;
    c.setR(10);
    cout << c.getS() << endl;
    return 0;
}

在类中直接定义函数时,不需要再函数名前面加上类名,因为函数属于哪一个类是不言而喻的。但当成员函数在类的外部定义时,就必须在函数名前面加上类名予以限定。“::”成为域解析符,用来连接类名和函数名,指明当前函数属于哪个类。
判断一个点与一个圆的位置关系


Point.h

#ifndef POINT_HH
#define POINT_HH

class Point
{
private:
    int X;
    int Y;
public:
    void setXY(int x, int y);
    int getDistance(Point &p);
};
#endif

Point.cpp

#include <iostream>
#include "Point.h"

using namespace std;

void Point::setXY(int x, int y)
{
    X = x;
    Y = y;
}

int Point::getDistance(Point &p) //把圆心的坐标传进来
{
    return (X - p.X) * (X - p.X) + (Y - p.Y) * (Y - p.Y);
}

Circle.h

#ifndef CIRCLE_HH
#define CIRCLE_HH

#include "Point.h"

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

Circle.cpp

#include <iostream>
#include "Point.h"
#include "Circle.h"

void Circle::setCircle(int x, int y, int r)
{
    m_p.setXY(x, y);
    m_r = r;
}

bool Circle::judge(Point &p)
{
    if(m_r * m_r > p.getDistance(m_p))
    {
        return true;
    }

    else
    {
        return false;
    }
}


main.cpp

#include <iostream>
#include "Circle.h"
#include "Point.h"

using namespace std;

int main()
{
    Circle c;
    c.setCircle(0, 0, 1);

    Point p;
    p.setXY(2, 2);

    if(c.judge(p))
    {
        cout << "在圆内" << endl;
    }

    else
    {
        cout << "在圆外" << endl;
    }
    return 0;
}

5.对象的构造与析构

构造函数的定义:

1)C++中的类可以定义与类名相同的特殊成员函数,这种与类名相同的成员函数叫做构造函数;
2)构造函数在定义时可以有参数;
3)没有任何返回类型的声明;

构造函数的调用:

自动调用:一般情况下C++编译器会自动调用构造函数
手动调用:在一些情况下则需要手工调用构造函数

析构函数的定义:

1)C++中的类可以定义一个特殊的成员函数清理对象,这个特殊的成员函数叫做析构函数
语法:~ClassName()
2)析构函数没有参数也没有任何返回类型的声明
3)析构函数在对象销毁时自动被调用

析构函数的调用:

C++编译器自动调用

#include <iostream>
#include <cstring>

using namespace std;

class Student
{
private:
    char name[32];
    int id;
public:
    Student(); //无参构造函数 
    Student(char *n, int i);//有参构造函数
    Student(const Student &s);//拷贝构造寒素
    void show();
};

//构造函数起到初始化的作用
Student::Student()
{    
    cout << "无参构造函数" << endl;
    strcpy(name, "aaa");
    id = 1;
}

Student::Student(char *n, int i)
{
    cout << "有参构造函数" << endl;
    strcpy(name, n);
    id = i;
}

Student::Student(const Student &s)
{
    cout << "拷贝构造函数" << endl;
    strcpy(name, s.name)
    id = s.id;
}
void Student::show()
{
    cout << name << " " << id << endl;
}

int main()
{
    Student stu1;//创建对象的时候编译器会自动的调用无参构造函数,编译器为每个类提供默认的无参构造函数
    stu1.show();
    
    Student stu2("bbb", 2);
    stu2.show();
    
    Student stu3 = Student("ccc", 3);
    stu3.show();

    Student stu4(stu3);//用对象stu3构造对象stu4的时候,编译器会为每个类型提供默认的拷贝构造函数
    stu4.show();
    return 0;
}

构造函数的规则:

1)当类中没有定义任何一个构造函数时,c++编译器会提供默认无参构造函数和默认拷贝构造函数
2)当类中定义了拷贝构造函数时,c++编译器不会提供无参数构造函数
3)当类中定义了任意的非拷贝构造函数(即:当类中提供了有参构造函数或无参构造函数),c++编译器不会提供默认无参构造函数
4 )默认拷贝构造函数成员变量简单赋值
总结:只要你写了构造函数,那么你必须用。

构造析构阶段性总结
1)构造函数是C++中用于初始化对象状态的特殊函数
2)构造函数在对象创建时自动被调用
3)构造函数和普通成员函数都遵循重载规则
4)拷贝构造函数是对象正确初始化的重要保证
5)必要的时候,必须手工编写拷贝构造函数
 

析构函数举例:

实现数组的初始化和释放

Array.h

#ifndef ARRAY_HH
#define ARRAY_HH

class Array
{
private:
    int length;
    int *data;
public:
    Array();
    Array(int l);
    void setVal(int index, int value);
    void getVal(int index);
    ~Array();//析构函数,没有参数,没有返回值,调用完成后自动释放对象
};

#endif 


Array.cpp

#include <iostream>
#include "Array.h"

using namespace std;

Array::Array()
{
    cout << "无参构造函数" << endl;
    length = 1;
    data = (int *)malloc(sizeof(int) * length);
}

Array::Array(int l)
{
    cout << "有参构造函数" << endl;
    length = l;
    data = (int *)malloc(sizeof(int) * length);
}

void Array::setVal(int index, int val)
{
    data[index] = val;
}

int Array::getVal(int index)
{
    return data[index];
}

Array::~Array()
{
    cout << "析构函数" << endl;
    free(data);
}

main.cpp

#include <iostream>
#include "Array.h"
using namespace std;

int main()
{
    Array a1(10); //自动调用有参构造函数,此时不会调用无参构造函数
    
    for(int i = 0; i < 10; i++)
    {
        a1.setVal(i, i + 1);
    }

    for(int i = 0; i < 10; i++)
    {
        cout << a1.getval(i) << endl;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/hu_junhua/article/details/86620596