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;
}