函数重载、初始化列表、复合类、析构函数、虚构函数
2016 6 16
函数重载:在同一个作用域中,函数名相同,参数列表不同,则多个函数构成重载。
参数列表不同分别为两种情况:参数个数不同;参数类型不同。
void func(1);
void func(1,2);
class p{
public:
func(int n1);
func(int n1,int n2);
}
p::func(int n1){
cout<<ni<<endl;
}
p::func(int n1,int n2)
{
cout<<n1<<n2<<endl;
}
//如果构造函数有默认值,创建对象不带参数,形参使用默认值。,带有参数->形参使用参数值
//不要让构造函数产生二异性(创建对象时,可以选择执行两个或者更多构造函数)
初始化列表
class p{
public:
void piont(int n1,int n2);
private:
int n;
int m;
}
p::point(int n1,int n2):n(n1),m(n2){}
初始化列表“:”开始“,”隔开后面紧跟函数体,
也就是:
p:point(int n1,int 2){
n=n1;
m=n2;
}
注意:
1.初始化列表只能出现在构造函数处,具体位置为:构造函数头部“:”开始“,”隔开后面紧跟函数体,
2.初始化列表优先于函数体执行,相比于函数体执行效率更高
3.有四种情况必须使用初始化列表对成员变量进行初始化:const成员变量;引用类型的成员变量;没有默认构造函数的类型成员变量;在继承关系中,基类部分的初始化需要使用初始化列表;
复合类:
一个类的成员变量是另外一个类的对象,那么前者被称为复合类
1.在示例中,Circle类中定义了一个Point类型的成员变量origin,那么Circle类为复合类;
2.如果构造函数中没有显示使用初始化列表初始化oringin,编译器会自动调用Point类中的默认构造对其进行初始化;否则根据实参列表调用匹配的构造函数初始化origin;
3.void Circle::print()const函数被const修饰,这种函数成员函数。const修饰函数时需要注意:const修饰函数时,只能修饰类中的成员函数;const成员函数体内不能修改成员变量的值;const成员函数体内如果要调用类中其他的成员函数,只能调用const成员函数;
声明文件(头文件)
#ifndef point_hpp
#define point_hpp
#include <stdio.h>
class Point{
public:
Point();
Point(float _x,float _y);
void print()const;
private:
float x;
float y;
};
#endif /* point_hpp */
实现文件
#include<iostream>
using namespace std;
#include "point.hpp"
Point::Point(){}
Point::Point(float _x,float _y){
x=_x;
y=_y;
}
void Point::print()const
{
cout<<"("<<x<<","<<y<<")"<<endl;
}
声明文件(头文件)
#ifndef circle_hpp
#define circle_hpp
#include <stdio.h>
#include"point.hpp"
class Circle
{
public:
Circle();
Circle(float x,float y,float r);
void setCircle(float r,Point p);
void print()const;
private:
float radius;
Point origin;
};
#endif /* circle_hpp */
实现文件
#include<iostream>
using namespace std;
#include "circle.hpp"
Circle::Circle(){}
Circle::Circle(float x,float y,float r):origin(x,y){
radius=r;
}
void Circle::setCircle(float r,Point p){
radius=r;
origin=p;
}
void Circle::print()const{
cout<<"radius:"<<radius<<endl;
origin.print();
}
测试文件
#include <iostream>
#include"point.hpp"
#include"circle.hpp"
int main(int argc, const char * argv[]) {
Point p(5,7);
p.print();
Circle c;
c.setCircle(1,p);
c.print();
std::cout << "Hello, World!\n";
return 0;
}
运行结果:
(5,7)
radius:1
(5,7)
Hello, World!
Program ended with exit code: 0
习题
//一个点类:属性:x,y行为:构造函数,输出函数
//直线类:属性:一个点A,一个点B,行为:构造函数,输出函数
//平面类:属性:一个直线,一个高(height)
//行为:构造函数,输出函数,计算面积函数,计算周长函数
析构函数
作用:当对象生命周期结束时,回收对象所占资源 eg:~Circle().
回收空间(回收构造函数时,在堆上开辟的空间)¥¥¥¥对象销毁时自动调用析构函数
析构函数有四个特点:(1、public 2、没有返回值 3、唯一(无参数))
1、没有返回值;
2、不能带参数;
3、不能被重载;
4、访问权限为公有
使用:
‘~’+类名
eg:
p(){ cout<<“shhhhhh”<
C:malloc
C++:new
1.一个空间
int *p=new int(3); //与malloc的功能相似
char *ch=new char(‘c’);
delete p; //free
delete ch;
2.一片连续空间
char *p1=new char[10];
int *p2=new int [20];
delete [] p1;
delete [] p2;
¥¥¥当属性里有指针的时候,指针空间必须在堆上
class text{ //头文件中
public:
text(int *_p);
~text();
private:
int *p;
};
text::text(int *_p){ //实现文件中
p=new int[5]; **//指针指向堆**
for(int i=0;i<5;i++)
{
p[i]=_p[i];
}
cout<<"调用构造函数"<<endl;
}
text::~text(){
if(p!=NULL)
{
delete [] p;
p=NULL;
}
cout<<"调用析构函数"<<endl;
}
//main测试
int main(int argc, const char * argv[]) {
int array[]={1,2,3,4,5};
{ //括号,为text t(array);的作用域
text t(array);
}
cout<<"测试结束"<<endl;
}
程序结果:
调用构造函数
调用析构函数
测试结束
Program ended with exit code: 0
习题
//一个点类:属性:x,y行为:构造函数,输出函数
//直线类:属性:一个点A,一个点B,行为:构造函数,输出函数
//平面类:属性:一个直线,一个高(height)
//行为:构造函数,输出函数,计算面积函数,计算周长函数
Point1声明(头文件)
#ifndef point1_hpp
#define point1_hpp
#include <stdio.h>
class Point1{
public:
Point1(float _x,float _y);
void print();
float getDistance(Point1 p);
private:
int x;
int y;
};
#endif /* point1_hpp */
Point1实现
#include "point1.hpp"
#include<iostream>
#include <math.h>
using namespace std;
Point1::Point1(float _x,float _y){
x=_x;
y=_y;
}
void Point1::print(){
cout<<"("<<x<<","<<y<<")"<<endl;
}
float Point1::getDistance(Point1 p){
return sqrt((x-p.x)*(x-p.x)+(y-p.y)*(y-p.y));
}
Line声明(头文件)
#ifndef line_hpp
#define line_hpp
#include "point1.hpp"
#include <stdio.h>
class Line{
public:
Line(Point1 a,Point1 b);
void print();
float getDistance();
private:
Point1 A;
Point1 B;
};
#endif /* line_hpp */
Line实现
#include "line.hpp"
#include<iostream>
using namespace std;
Line::Line(Point1 a,Point1 b):A(a),B(b){
}
void Line::print(){
A.print();//错了两次!
B.print();
}
float Line::getDistance(){//线类中,本身含两个点,不需要再带两个点类的参数:Point1 p1,Point1 p2
return A.getDistance(B);
}
Plane声明(头文件)
#ifndef plane_hpp
#define plane_hpp
#include "line.hpp"
#include <stdio.h>
class Plane{
public:
Plane(Line _l,float h);
void print();
float getArea();
float getPrae();
private:
Line l;
int height;
};
#endif /* plane_hpp */
Plane实现
#include "plane.hpp"
#include<math.h>
#include<iostream>
using namespace std;
Plane::Plane(Line _l,float h):l(_l),height(h){
}
void Plane::print(){
l.print();
cout<<"heigth:"<<height<<endl;
}
float Plane::getArea(){ //不用再带参数 自身已有一条线
return l.getDistance()*height;
}
float Plane::getPrae(){ //不用再带参数 自身已有一条线
return 2*(l.getDistance()+height);
}
main函数 测试
#include <iostream>
using namespace std;
#include "line.hpp"
#include "plane.hpp"
#include "point1.hpp"
int main(int argc, const char * argv[]) {
Point1 p1(8,9);
Point1 p2(3, 4);
p1.print();
p2.print();
Line l(p1,p2);
l.print();
cout<<l.getDistance()<<endl;
Plane plane(l, 5);
cout<<plane.getArea()<<endl;
cout<<plane.getPrae()<<endl;
}