创建一个点的类,要求能输入和输出点
创建一个圆的类,要求能输入和输出圆
要求创建一个方法,能比较点和圆的关系
.h文件中
#pragma once
class Point
{
public:
void setX(int X);
void setY(int Y);
int getX();
int getY();
private:
int x;
int y;
};
.cpp文件中
#include "Point.h"
void Point::setX(int X)
{
x = X;
}
void Point::setY(int Y)
{
y = Y;
}
int Point::getX()
{
return x;
}
int Point::getY()
{
return y;
}
在.cpp文件中要想调用.h文件中的成员变量,除了需要添加头文件,还需要在函数前加入作用域
.h文件中
#pragma once
#include"Point.h"
class Circle
{
public:
void setMHear(Point MHear);
void setMHear(int x, int y);
void setMR(int MR);
Point getMHear();
int getMR();
void isPointAndCircle(Point &p);
private:
Point mHear;
int mR;
};
在.h文件中,因为圆需要有圆心,圆心也是一个点,所以这里直接引入点的类,在圆的类中之间以私有权限创建一个点的对象,以充当圆心
.cpp文件中
#include "Circle.h"
#include
using namespace std;
void Circle::setMHear(Point p)
{
mHear.setX(p.getX());
mHear.setY(p.getY());
}
void Circle::setMHear(int x, int y)
{
mHear.setX(x);
mHear.setY(y);
}
void Circle::setMR(int MR)
{
mR = MR;
}
Point Circle::getMHear()
{
return mHear;
}
int Circle::getMR()
{
return mR;
}
void Circle::isPointAndCircle(Point &p)
{
double distance = pow(p.getX() - mHear.getX(), 2) + pow(p.getY() - mHear.getY(), 2);
double tempR = pow(mR, 2);
if (distance == tempR)
{
cout << "点在圆上" << endl;
}
else if (distance < tempR)
{
cout << "点在圆内" << endl;
}
else {
cout << "点在圆外" << endl;
}
}
由于深拷贝和浅拷贝的区别,在传入点的形参建立圆心的对象时,我们不直接拷贝点,而是利用点里面的获取x和y来赋予圆心
在写比较函数时,要秉持高内聚低耦合的设计理念,将半径和两点距离分开写,别都堆在if语句中
void G_isPointAndCircle(Circle& c, Point& p)
{
//获取点和圆之间的距离
double distance = pow(p.getX() - c.getMHear().getX(), 2) + pow(p.getY() - c.getMHear().getY(), 2);
//半径的平方
double tempR = pow(c.getMR(), 2);
if (distance == tempR)
{
cout << "全局 点在圆上" << endl;
}
else if (distance < tempR)
{
cout << "全局 点在圆内" << endl;
}
else {
cout << "全局 点在圆外" << endl;
}
}
void test()
{
Point p;
p.setX(30);
p.setY(40);
Circle c;
c.setMR(50);
c.setMHear(0, 0);
c.isPointAndCircle(p);
c.setMHear(p);
G_isPointAndCircle(c, p);
}
全局函数在写的时候由于不能直接调用类里的成员变量并直接获取它的值,所以需要两次get函数来获取。
传入参数时,记得要加&取地址符
构造函数的作用是初始化成员变量
析构函数运行在对象销毁前
构造函数和析构函数都是编译器去调用的
当没有构造函数时,直接将成员变量赋值给全局变量,会报错
在实例化对象时,内部做了两件事,分配空间(栈区),调用构造函数进行初始化
class Maker {
public:
//构造函数的作用是初始化成员变量,是编译器去调用的
//无参构造
Maker()
{
a = 10;
cout << "构造函数" << endl;
}
//析构函数,在对象销毁前,编译器调用析构函数
~Maker()
{
cout << "析构函数" << endl;
}
public:
int a;
};
void test01()
{
//实例化对象,内部做了两件事,分配空间(栈区),调用构造函数进行初始化
Maker m;
int b = m.a;
cout << b << endl;
}
在mian函数中调用test01函数时,实例化对象m后,会运行一次构造函数,打印一次构造函数,然后逐步执行下来,打印一次b的值,函数运行结束前,运行一次析构函数。
在main函数中,实例化一次对象,将其放在test01后面,在上述打印完成后,才会打印一次构造函数,然后运行至return0,主函数结束,然后出现输入任意键退出,退出后,打印一次析构函数,并关闭程序
//析构函数的作用
class Maker2
{
public:
//有参构造
Maker2(const char * name,int age)
{
cout << "有参构造" << endl;
//从堆区空间申请
pName = (char*)malloc(strlen(name) + 1);
strcpy(pName, name);
mAge = age;
}
void printMaker2()
{
cout << "name:" << pName << " age:" << mAge << endl;
}
~Maker2()
{
cout << "析构函数" << endl;
//释放堆区空间
if (pName != NULL)
{
free(pName);
pName = NULL;
}
}
private:
char* pName;
int mAge;
};
构造函数分为有参构造和无参构造,
有参构造可以用malloc从堆区空间申请一块空间,我们都知道malloc完需要free掉,所以在这个类的析构函数中,我们可以写free函数
class Maker3
{
public:
//注意1:构造函数可以重构
Maker3()//无参构造函数
{
}
Maker3(int a)//有参构造函数
{
}
};
class Maker
{
public :
Maker()//默认的构造函数,函数体是空的
{
}
~Maker()//默认的析构函数,函数体也是空的
{
}
//编译器默认提供默认的构造函数和析构函数
void printfMaker()
{
a = 100;
cout << "a = " << a << endl;
}
private:
int a;
};
class Maker
{
public:
Maker()
{
cout << "无参构造函数" << endl;
a = 20;
}
//拷贝构造函数
Maker(const Maker &m)
{
cout << "拷贝构造函数" << endl;
a = m.a;
}
//打印函数
void printMaker()
{
cout << "a = " << a << endl;
}
private:
int a;
};
void test01()
{
Maker m1;
m1.printMaker();
//用一个已有的对象去初始化另一个对象
Maker m2(m1);
m2.printMaker();
}
传入const Maker &m是为了不让类修改函数里面的传入的变量,所以只能引用传递不能值传递
默认拷贝构造函数进行了成员变量的简单拷贝
class Maker2
{
public:
Maker2()
{
cout << "无参构造函数" << endl;
a = 20;
}
//编译器提供了默认的拷贝构造函数
//Maker2(const Maker2& m)
//{
// //默认拷贝构造函数进行了成员变量的简单拷贝
// a = m.a;
//}
//打印函数
void printMaker()
{
cout << "a = " << a << endl;
}
private:
int a;
};
void test02()
{
Maker2 m1;
m1.printMaker();
//用一个已有的对象去初始化另一个对象
Maker2 m2(m1);
m2.printMaker();
}
因为用的是引用,所以不是本身,是别名
如果拷贝构造函数中的形参不是引用
/*
Maker3(const Maker3 m)//const Maker3 m = m1;
{
cout << “拷贝构造函数” << endl;
}
1.Maker3 m2(m1);
2.const Maker3 m = m1;
3.const Maker3 m(m1);
4.const Maker3 m = m1;
5.进入死循环
*/
class Maker3
{
public :
Maker3(int Ma)
{
cout << "有参构造函数" << endl;
ma = Ma;
}
Maker3(const Maker3 &m)
{
cout << "拷贝构造函数" << endl;
}
private:
int ma;
};
void test03()
{
Maker3 m1(10);//调用有参构造
Maker3 m2(m1);
}
void test()
{
Maker m;//调用无参构造函数
Maker m1(10);//调用有参构造
Maker m2(m1);//调用拷贝构造
//不常用
Maker m4 = Maker(10);//调用的是有参构造函数
Maker m3 = m2 ;//调用拷贝构造
cout << "= = = = ="<<endl;
Maker m5 = 10;//Maker m5 = Maker(10);
Maker m6;
m6 = m5;//赋值操作
}
匿名对象的生命周期在当前行
如Maker();
注意:如果匿名对象由名字来接,那么就不是匿名对象
如Maker m1 = Maker();
void func(Maker m)//Maker m = m1;
{
}
void test01()
{
Maker m1;
func(m1);
}
void test02()
{
Maker m1;
Maker m2(m1);
}
Maker func2()
{
//局部对象
Maker m;
cout << "局部对象的地址" << &m << endl;
return m;
}
void test03()
{
Maker m1 = func2();
cout << "m1对象的地址:" << &m1 << endl;
}
void test01()
{
//Maker m;//err
//Maker m(10);//调用有参构造
//Maker m2(m);//调用默认的拷贝构造函数
}
void test02()
{
//Maker m;
}
class BMW
{
public:
BMW()
{
cout << "BMW有参构造" << endl;
}
~BMW()
{
cout << "BMW析构" << endl;
}
};
class Buick
{
public:
Buick()
{
cout << "Buick构造" << endl;
}
~Buick()
{
cout << "Buick析构" << endl;
}
};
class Maker
{
public:
Maker()
{
cout << "Maker构造" << endl;
}
~Maker()
{
cout << "Maker析构" << endl;
}
private:
BMW bmw;//成员对象
Buick bui;//成员对象
};
初始化列表是调用成员对象的指定构造函数
注意1:初始化列表只能写在构造函数
class BMW2
{
public:
BMW2(int a)
{
cout << "BMW有参构造2" << a << endl;
}
~BMW2()
{
cout << "BMW析构2" << endl;
}
};
class Buick2
{
public:
Buick2(int x, int y)
{
cout << "Buick构造2" << endl;
}
~Buick2()
{
cout << "Buick析构2" << endl;
}
};
class Maker2
{
public:
//Maker2() :bmw2(10)
//{
// cout << "Maker构造2" << endl;
//}
Maker2(int a) :bmw2(a),bui2(10,20)
{
cout << "Maker构造2" << endl;
}
Maker2(const Maker& m2):bmw2(40),bui2(10,20)
{
cout << "Maker拷贝构造2" << endl;
}
~Maker2()
{
cout << "Maker析构2" << endl;
}
private:
BMW2 bmw2;//成员对象
Buick2 bui2;//成员对象
};
注意2:如果使用了初始化列表,那么所有的构造函数都要写初始化列表
注意3:如果有多个对象需要指定调用某个构造函数,用逗号隔开
注意4:可以使用对象的构造函数传递数值给成员对象的变量
class Student
{
public:
Student(const char* name, int Age)
{
pName = (char*)malloc(strlen(name) + 1);
strcpy(pName, name);
age = Age;
}
~Student()
{
cout << "析构函数" << endl;
if (pName != NULL)
{
free(pName);
pName = NULL;
}
}
public:
char* pName;
int age;
};
void test02()
{
Student s1("小花", 18);
Student s2(s1);//调用默认的拷贝构造函数
cout << "s1 Name = " << s1.pName << " s1 age = " << s1.age << endl;
cout << "s2 Name = " << s2.pName << " s2 age = " << s2.age << endl;
}
//深拷贝
Student(const Student &stu)
{
cout << "重写的拷贝构造函数" << endl;
//1.申请空间
pName = (char*)malloc(strlen(stu.pName) + 1);
//2.拷贝数据
strcpy(pName, stu.pName);
age = stu.age;
}