构造函数与析构函数

1、构造函数
1.1 构造函数具有一些特殊的性质
1.2 定义构造函数的一般形式
1.3 利用构造函数创建对象
2、成员初始化表
3、缺省参数的构造函数
4、重载构造函数
5、拷贝构造函数
5.1 自定义拷贝构造函数
5.2 缺省的拷贝构造函数
5.3 调用拷贝构造函数的三种情况
5.4 浅拷贝和深拷贝
6、析构函数
7、调用构造函数和析构函数的顺序
8、对象的生存期
创一个小群,供大家学习交流聊天
如果有对学C++方面有什么疑惑问题的,或者有什么想说的想聊的大家可以一起交流学习一起进步呀。
也希望大家对学C++能够持之以恒
C++爱好群,
如果你想要学好C++最好加入一个组织,这样大家学习的话就比较方便,还能够共同交流和分享资料,给你推荐一个学习的组织:快乐学习C++组织 可以点击组织二字,可以直达

构造函数和析构函数都是类的成员函数,但它们都是特殊的成员函数,执行特殊的功能,不用调用便自动执行,而且这些函数的名字与类的名字有关。

C++语言中有一些成员函数性质是特殊的,这些成员函数负责对象的建立、删除。这些函数的特殊性在于可以由编译器自动地隐含调用,其中一些函数调用格式采用运算符函数重载的语法。

C++引进一个自动完成对象初始化过程的机制,这就是类的构造函数。

对象的初始化

1、数据成员是不能在声明类时初始化
2、类型对象的初始化方法:
1) 调用对外接口(public成员函数)实现:声明类→定义对象→调用接口给成员赋值
2) 应用构造函数(constructor) 实现:声明类→定义对象→同时给成员赋值

1、构造函数

构造函数是一种特殊的成员函数,它主要用于为对象分配空间,进行初始化。

1.1 构造函数具有一些特殊的性质:

(1) 构造函数的名字必须与类名相同。
(2) 构造函数可以有任意类型的参数,但不能指定返回类型。 它有隐含的返回值,该值由系统内部使用。
(3) 构造函数是特殊的成员函数,函数体可写在类体内,也可写在类体外。
(4) 构造函数可以重载,即一个类中可以定义多个参数个数或参数类型不同的构造函数。构造函数是不能继承
(5) 构造函数被声明为公有函数,但它不能像其他成员函数那样被显式地调用,它是在定义对象的同时被调用的。
(6) 在声明类时如果没有定义类的构造函数,编译系统就会在编译时自动生成一个默认形式的构造函数,
(7) 默认构造函数是构造对象时不提供参数的构造函数。
(8) 除了无参数构造函数是默认构造函数外,带有全部默认参数值的构造函数也是默认构造函数。
(9) 自动调用:构造函数在定义类对象时自动调用, 不需用户调用,也不能被用户调用。在对象使用前调用。
(10) 调用顺序:在对象进入其作用域时(对象使用前) 调用构造函数。

1.2 定义构造函数的一般形式

class 类名
{
public:
类名(形参表) ; //构造函数的原型
//类的其它成员
};
类名::类名(形参表) //构造函数的实现
{
//函数体
}

1.3 利用构造函数创建对象

(1) 利用构造函数直接创建对象.其一般形式为:类名 对象名[(实参表)];

这里的“类名”与构造函数名相同,“实参表”是为构造函数提供的实际参数。

例2.7 为类Date建立一个构造函数

#include <iostream.h>
class Date {
public:
Date(int y,int m,int d); // 构造函数
void setDate(int y,int m,int d);
void showDate();
private:
int year, month, day;
};
Date::Date(int y,int m,int d) // 构造函数的实现
{ year=y; month=m; day=d; }
void Date::setDate(int y,int m,int d)
{ year=y; month=m; day=d; }
inline void Date::showDate()
{ cout<<year<<"."<<month<<"."<<day<<endl; }

例2.8 利用构造函数直接创建对象

#include <iostream.h>
class Date {
// 省略, 同例2.7
};
// 省略, 同例2.7
void main()
{
Date date1(1998,4,28); // 定义类Date的对象date1,
// 自动调用date1的构造函数,初始化对象date1
cout<<"Date1 output1:"<<endl;
date1.showDate(); // 调用date1的showDate(),显示date1的数据
date1.SetDate(2002,11,14); // 调用date1的setDate(),
// 重新设置date1的数据
cout<<"Date1 output2:"<<endl;
date1.showDate(); // 调用date1的showDate(),显示date1的数据
}

constructing...
Date1 output1:
1998.4.28
Date1 output2:
2002.11.14

(2) 利用构造函数创建对象时,通过指针和new来实现。其一般语法形式为:
类名 *指针变量 = new 类名[(实参表)];

void main()
{
Date date1;
date1=new Date(1998,4,28);
//可合写成:Date
date1=new Date(1998,4,28);
cout<<"Date1 output1:"<<endl;
date1->showDate();
date1->setDate(2002,11,14);
cout<<"Date1 output2:"<<endl;
date1->showDate();
delete date1;
}

说明:

构造函数的名字必须与类名相同,否则编译器将把它当作一般的成员函数来处理。
构造函数是不能说明它的返回值类型的,甚至说明为void类型也不行。
构造函数可以是不带参数的。

class A{
public:
A();
//…
private:
int x;
};
A∷A()
{
cout<<"initialized \n";
x=50;
}
main()
{
A a;

}


有两个长方柱,其长、宽、高分别为:(1)12,25,30;(2)15,30,21。求它们的体积。要求:编一个基于对象的程序,在类中用带参数的构造函数。

class Box{
public:
Box(int,int,int);
int volume( );
private:
int height;
int width;
int length;
};
Box::Box(int h,int w,int len)
{
height = h;
width = w;
length = len;
}
int Box::volume( )
{
return heightwidthlength;
}
int main( )
{
Box box1(12,25,30);
cout << box1.volume( ) << endl;
Box box2(15,30,21);
cout << box2.volume( ) << endl;
return 0;
}

2、成员初始化表

对于常量类型和引用类型的数据成员,不能在构造函数中用赋值语句直接赋值,C++提供初始化表进行置初值。

带有成员初始化表的构造函数的一般形式如下:

类名::构造函数名([参数表])[:(成员初始化表)]
{
// 构造函数体
}

成员初始化表的一般形式为:

数据成员名1(初始值1),数据成员名2(初始值2),……

例2.9 成员初始化表的使用

#include<iostream.h>
class A{
public:
A(int x1):x(x1),rx(x),pi(3.14) // rx(x)相当于rx=x, pi(3.14)相当于pi=3.14
{ }
void print()
{cout<<"x="<<x<<" "<<"rx="<<rx<<" "<<"pi="<<pi;}
private:
int x; int& rx; const float pi;
};
main()
{
A a(10);
a.print();
return 0;
}
构造函数采用成员初始化表对数据成员进行初始化,是一些程序员喜欢使用的方法。

class B{
int i;
char j;
float f;
public:
B(int I, char J, float F)
{ i=I; j=J; f=F; };
};

class B{
public:
B(int I,char J,float F):i(I),j(J),f(F)
{ }
private:
int i;
char j;
float f;
};

说明

如果需要将数据成员存放在堆中或数组中,则应在构造函数中使用赋值语句,即使构造函数有成员初始化表也应如此。

class C{
public:
C(int I,char Ch,float F,char N[]):i(I),ch(Ch),f(F)
{ strcpy (name,N);}
private:
int i;
char ch;
float f;
char name[25];
};

类成员是按照它们在类里被声明的顺序初始化的,与它们在初始化表中列出的顺序无关。

【例2.10】

#include<iostream.h>
class D {
public:
D(int i):mem2(i),mem1(mem2+1)
{
cout<<"mem1: "<<mem1<<endl;
cout<<"mem2: "<<mem2<<endl;
}
private:
int mem1;
int mem2;
};
void main()
{
D d(15);
}

mem1: -858993459
mem2: 15

3、缺省参数的构造函数

例2.11

#include<iostream.h>
class Coord {
public:
Coord(int a=0,int b=0){ x=a; y=b;} // 带有缺省参数的构造函数
int getx(){ return x; }
int gety(){ return y; }
private:
int x,y;
};
void main()
{
Coord op1(5,6); Coord op2(5); Coord op3;
int i,j;
i=op1.getx();j=op1.gety();
cout<<"op1 i= "<<i<<" op1 j= "<<j<<endl;
i=op2.getx();j=op2.gety();
cout<<"op2 i= "<<i<<" op2 j= "<<j<<endl;
i=op3.getx();j=op3.gety();
cout<<"op3 i= "<<i<<" op3 j= "<<j<<endl;
}

class Box{
public:
Box(int h=10,int w=10,int l=10); //在声明构造函数时指定默认参数
int volume( ){ return(heightwidthlength); }
private:
int height;
int width;
int length;
};
Box:: Box(int h,int w,int l) //在定义函数时可以不指定默认参数
{
height=h;
width=w;
length=l;
}

4、重载构造函数

构造函数的重载

在一个类中可以定义多个构造函数,以便对类对象提供不同的初始化的方法,供用户选用。这些构造函数具有相同的名字,而参数的个数或参数的类

型不相同(这称为构造函数的重载)

关于构造函数重载的说明

(1) 默认构造函数:一个调用构造函数时不必给出实参的构造函数。 显然,无参的构造函数属于默认构造函数。一个类只能有一个默认构造函数。
(2) 尽管在一个类中可以包含多个构造函数,但是对于每一个对象来说,建立对象时只执行其中一个构造函数,并非每个构造函数都被执行。

class Box{
public:
Box(int h, int w, int l): height(h),width(w),length(l) { }
Box();
int volume( );
private:
int height;
int width;
int length;
};
Box::Box()
{
height = 10;
width = 10;
lenght = 10;
}
int Box::volume( )
{
return heightwidthlength;
}
int main( )
{
Box box1; // 书上为 box1();
cout << box1.volume( ) << endl;
Box box2(15,30,25);
cout << box2.volume( ) << endl;
return 0;
}

例2.17 重载构造函数应用例程。

#include <iostream.h>
class Date{
public:
Date(); // 无参数的构造函数
Date(int y,int m,int d); // 带有参数的构造函数
void showDate();
private:
int year, month, day;
};
Date::Date()
{ year=1998; month=4; day=28; }
Date::Date( int y, int m, int d)
{ year=y; month=m; day=d; }
inline void Date::showDate()
{ cout<<year<<"."<<month<<"."<<day<<endl; }
void main()
{
Date date1; // 声明类Date的对象date1,
// 调用无参数的构造函数
cout<<"Date1 output: "<<endl;
date1.showDate(); // 调用date1的showDate(),显示date1的数据
Date date2(2002, 11, 14); // 定义类Date的对象date2,
// 调用带参数的构造函数
cout<<"Date2 output: "<<endl;
date2.showDate(); // 调用date2的showDate(),显示date2的数据
}

运行结果:

Date1 output:
1998.4.28
Date2 output:
2002.11.14

例2.18 关于计时器的例子

#include<iostream.h>
#include<stdlib.h>
class timer{
public:
timer() // 无参数构造函数,给seconds清0
{ seconds=0; }
timer(char t) // 含一个数字串参数的构造函数
{ seconds=atoi(t); }
timer(int t) // 含一个整型参数的构造函数
{ seconds=t; }
timer(int min,int sec) // 含两个整型参数的构造函数
{ seconds=min
60+sec; }
int gettime()
{ return seconds; }
private:
int seconds;
};
main()
{
timer a,b(10),c("20"),d(1,10);
cout<<"seconds1="<<a.gettime()<<endl;
cout<<"seconds2="<<b.gettime()<<endl;
cout<<"seconds3="<<c.gettime()<<endl;
cout<<"seconds4="<<d.gettime()<<endl;
return 0;
}

class x {
public:
x(); // 没有参数的构造函数
x(int i=0); // 带缺省参数的构造函数
};
//…
void main()
{
x one(10); // 正确,调用x(int i=0)
x two; // 存在二义性
//…
}

5、拷贝构造函数

拷贝构造函数是一种特殊的构造函数,其形参是本类对象的引用。其作用是使用一个已经存在的对象去初始化另一个同类的对象。

通过等于号复制对象时,系统会自动调用拷贝构造函数。
拷贝构造函数与原来的构造函数实现了函数的重载。

拷贝构造函数具有以下特点:

(1) 因为该函数也是一种构造函数,所以其函数名与类名相同,并且该函数也没有返回值类型。
(2) 该函数只有一个参数,并且是同类对象的引用。
(3) 每个类都必须有一个拷贝构造函数。程序员可以根据需要定义特定的拷贝构造函数,以实现同类对象之间数据成员的传递。如果程序员没有定义类的拷贝构造函数,系统就会自动生成产生一个缺省的拷贝构造函数。

5.1 自定义拷贝构造函数

自定义拷贝构造函数的一般形式如下:

class 类名{
public :
类名(形参); //构造函数
类名(类名 &对象名); //拷贝构造函数
...
};
类名:: 类名(类名 &对象名) //拷贝构造函数的实现
{ 函数体 }

用户自定义拷贝构造函数

class Coord{
int x,y;
public:
Coord(int a, int b) // 构造函数
{
x=a;
y=b;
cout<<"Using normal constructor\n";
}
Coord(const Coord& p) // 拷贝构造函数
{
x=2p.x;
y=2
p.y;
cout<<"Using copy constructor\n";
}
//…
};

如果p1、 p2为类Coord的两个对象,p1已经存在,则coord p2(p1)调用拷贝构造函数来初始化p2

例2.19 自定义拷贝构造函数的使用

#include<iostream.h>
class Coord {
public:
Coord(int a,int b) // 构造函数
{ x=a; y=b; cout<<"Using normal constructor\n";}
Coord(const Coord& p) // 拷贝构造函数
{ x=2p.x; y=2p.y; cout<<"Using copy constructor\n";}
void print(){ cout<<x<<" "<<y<<endl; }
private:
int x,y;
};
main()
{
Coord p1(30,40); // 定义对象p1,调用了普通的构造函数
Coord p2(p1); // 以“代入” 法调用拷贝构造函数,用对象p1初始化对象p2
p1.print();
p2.print();
return 0;
}

除了用代入法调用拷贝构造函数外,还可以采用赋值法调用拷贝构造函数,如:

main()
{
Coord p1(30,40);
Coord p2=p1; //以"赋值"法调用拷贝构造函数,
用对象p1初始化对象p2
//…
}

5.2 缺省的拷贝构造函数

如果没有编写自定义的拷贝构造函数,C++会自动地将一个已存在的对象复制给新对象,这种按成员逐一复制的过程由是缺省拷贝构造函数自动完成的。

例2.20 调用缺省的拷贝构造函数

#include<iostream.h>
class Coord{
public:
Coord(int a,int b)
{ x=a; y=b; cout<<"Using normal constructor\n"; }
void print(){ cout<<x<<" "<<y<<endl;}
private:
int x,y;
};
main()
{
Coord p1(30,40); // 定义类Coord的对象p1,
// 调用了普通构造函数初始化对象p1
Coord p2(p1); // 以“代入”法调用缺省的拷贝构造函数,
// 用对象p1初始化对象p2
Coord p3=p1; // 以“赋值”法调用缺省的拷贝构造函数,
// 用对象p1初始化对象p3
p1.print(); p2.print(); p3.print();
return 0;
}

5.3 调用拷贝构造函数的三种情况

(1) 当用类的一个对象去初始化该类的另一个对象时。

Coord p2(p1); // 用对象p1初始化对象p2, 拷贝构造函数被调用(代入法)
Coord p3=p1; // 用对象p1初始化对象p3, 拷贝构造函数被调用(赋值法)

(2) 当函数的形参是类的对象,调用函数,进行形参和实参结合时。

//…
fun1(Coord p) // 函数的形参是类的对象
{
p.print();
}
main()
{
Coord p1(10,20);
fun1(p1); // 当调用函数,进行形参和实参结合时,
调用拷贝构造函数
return 0;
}

(3) 当函数的返回值是对象,函数执行完成,返回调用者时。

// …
Coord fun2()
{
Coord p1(10,30);
return p1;
} // 函数的返回值是对象
main()
{
Coord p2;
P2=fun2(); // 函数执行完成,返回调用者时,调用拷贝构造函数
return 0;
}

5.4 浅拷贝和深拷贝

所谓浅拷贝,就是由缺省的拷贝构造函数所实现的数据成员逐一赋值,若类中含有指针类型数据, 则会产生错误。

为了解决浅拷贝出现的错误,必须显示地定义一个自己的拷贝构造函数,使之不但拷贝数据成员,而且为对象1和对象2分配各自的内存空间,这就是所谓的深拷贝。

例2.23 浅拷贝例子

#include<iostream.h>
#include<string.h>
class Student {
public:
Student(char name1,float score1);
~Student();
private:
char
name; // 学生姓名
float score; // 学生成绩
};
Student∷Student(char *name1,float score1)
{
cout<<"Constructing..."<<name1<<endl;
name=new char[strlen(name1)+1];
if (name !=0)
{
strcpy(name,name1);
score=score1;
}
}
Student∷~Student()
{
cout<<"Destructing..."<<name<<endl;
name[0]='\0';
delete name;
}
void main()
{
Student stu1("liming",90); // 定义类Student的对象stu1
Student stu2=stu1; // 调用缺省的拷贝构造函数
}

Constructing... liming
Destructing... liming
Destructing...

浅拷贝示意图

例2.24 深拷贝例子

#include<iostream.h>
#include<string.h>
class Student {
private:
char name; // 学生姓名
float score; // 学生成绩
public:
Student(char
name1,float score1);
Student(Student& stu);
~Student();
};
Student∷Student(char *name1,float score1)
{
cout<<"constructing..."<<name1<<endl;
name=new char[strlen(name1)+1];
if (name !=0)
{
strcpy(name,name1);
score=score1;
}
}
Student∷Student(Student& stu)
{
cout<<"Copy constructing..."<<stu.name<<endl;
name=new char[strlen(stu.name)+1];
if (name !=0)
{
strcpy(name,stu.name);
score=stu.score;
}
}
Student∷~Student()
{
cout<<"Destructing..."<<name<<endl;
name[0]='\0';
delete name;
}
void main()
{
Student stu1("liming", 90); // 定义类Student的对象stu1,
Student stu2=stu1; // 调用自定义的拷贝构造函数
}

深拷贝示意图

6、析构函数

析构函数也是一种特殊的成员函数。它执行与构造函数相反的操作,通常用于撤消对象时的一些清理任务,如释放分配给对象的内存空间等。

析构函数有以下一些特点:
① 析构函数与构造函数名字相同,但它前面必须加一个波浪号(~);
② 析构函数没有参数,也没有返回值,而且不能重载。因此在一个类中只能有一个析构函数;
③ 当撤消对象时,编译系统会自动地调用析构函数。 如果程序员没有定义析构函数,系统将自动生成和调用一个默认析构函数,默认析构函数只能释放对象的数据成员所占用的空间,但不包括堆内存空间。

例2.25 重新说明类Date

#include <iostream.h>
class Date{
public:
Date(int y,int m,int d); // 构造函数
~Date(); // 析构函数
void setDate(int y,int m,int d);
void showDate();
private:
int year, month, day;
};
Date::Date(int y,int m,int d) // 构造函数的实现
{
cout<<"constructing..."<<endl;
year=y;month=m; day=d;
}
Date::~Date() // 析构函数的实现
{ cout<<"destruting..."<<endl; }
void Date::setDate(int y,int m,int d)
{ year=y;month=m;day=d; }
inline void Date::showDate()
{ cout<<year<<"."<<month<<"."<<day<<endl; }
void main()
{
Date date1(1998,4,28); // 定义类Date的对象date1,
// 调用date1的构造函数,初始化对象date1
cout<<"Date1 output1:"<<endl;
date1.showDate(); // 调用date1的showDate(),显示date1的数据
date1.setDate(2002,11,14); // 调用date1的setDate(),
// 重新设置date1的数据
cout<<"Date1 output2:"<<endl;
date1.showDate(); // 调用date1的showDate(),显示date1的数据
}

析构函数被调用的两种情况

1) 若一个对象被定义在一个函数体内,当这个函数结束时,析构函数被自动调用。
2) 若一个对象是使用new运算符动态创建,在使用delete释放时,自动调用析构函数。

【例2.13】 较完整的学生类例子

#include<iostream.h>
#include<string.h>
class Student {
public:
Student(char name1,char stu_no1,float score1); // 构造
函数
~Student(); // 析构函数
void modify(float score1); // 修改数据
void show(); // 显示数据
private:
char name; // 学生姓名
char
stu_no; // 学生学号
float score; // 学生成绩
};
Student∷Student(char name1,char stu_no1,float score1)
{
name=new char[strlen(name1)+1];
strcpy(name,name1);
stu_no=new char[strlen(stu_no1)+1];
strcpy(stu_no,stu_no1);
score=score1;
}
Student∷~Student()
{
delete []name;
delete []stu_no;
}
void Student∷modify(float score1)
{ score=score1; }
void Student∷show()
{
cout<<"\n name: "<<name;
cout<<"\n stu_no: "<<stu_no;
cout<<"\n score: "<<score;
}
void main()
{
Student stu1("Liming","990201",90); // 定义类Student的对象stu1,
// 调用stu1的构造函数,初始化对象stu1
stu1.show(); // 调用stu1的show(),显示stu1的数据
stu1.modify(88); // 调用stu1的modify(),修改stu1的数据
stu1.show(); // 调用stu1的show(),显示stu1修改后的数据
}

ame:Liming
stu_no:990201
score:90
name:Liming
stu_no:990201
score:88

缺省的析构函数

每个类必须有一个析构函数。

若没有显式地为一个类定义析构函数,编译系统会自动地生成一个缺省的析构函数

其格式如下:类名::析构函数名( ){ }

class string_data {
public:
string_data(char )
{ str=new char[max_len];}
~string_data()
{ delete []str;}
void get_info(char
);
void sent_info(char );
private:
char
str;
int max_len;
};

7、调用构造函数和析构函数的顺序

1) 一般顺序

调用析构函数的次序正好与调用构造函数的次序相反:最先被调用的构造函数,其对应的(同一对象中的)析构函数最后被调用,而最后被调用的构造函数,其对应的析构函数最先被调用。

2) 全局对象

在全局范围中定义的对象(即在所有函数之外定义的对象),它的构造函数在所有函数(包括main函数)执行之前调用。在程序的流程离开其作用域时(如main函数结束或调用exit函数)时,调用该全局对象的析构函数。

3) auto局部对象

局部自动对象(例如在函数中定义的对象),则在建立对象时调用其构造函数。如果函数被多次调用,则在每次建立对象时都要调用构造函数。在函数调用结束、对象释放时先调用析构函数。

4) static局部对象

如果在函数中定义静态局部对象,则只在程序第一次调用此函数建立对象时调用构造函数一次,在调用结束时对象并不释放,因此也不调用析构函数,只在main函数结束或调用exit函数结束程序时,才调用析构函数。

  1. 对象的生存期

对象按生存期的不同分为如下几种:

(1) 局部对象

当对象被定义时,调用构造函数,该对象被创建;当程序退出该对象所在的函数体或程序块时,调用析构函数,对象被释放。
局部对象是被定义在一个函数体或程序块内的,它的作用域限定在函数体或程序块内,生存期较短。

(2) 全局对象

当程序开始运行时,调用构造函数,该对象被创建;当程序结束时,调用析构函数,该对象被释放。
静态对象是被定义在一个文件中,它的作用域从定义是起到文件结束时为止。生存期较长。

(3) 静态对象

当程序中定义静态对象时,调用构造函数,该对象被创建;当整个程序结束时,调用析构函数,对象被释放。
全局对象是被定义在某个文件中,它的作用域包含在该文件的整个程序中,生存期是最长的。

(4) 动态对象

执行new运算符调用构造函数,动态对象被创建;用delete释放对象时,调用析构函数。
动态对象是由程序员掌握的,它的作用域和生存期是由new和delete之间的间隔决定的。

类的应用举例(例)

一圆形游泳池如图所示,现在需在其周围建一圆形过道,并在其四周围上栅栏。栅栏价格为35元/米,过道造价为20元/平方米。过道宽度为3米,游泳池半径由键盘输入。要求编程计算并输出过道和栅栏的造价。

#include <iostream>
using namespace std;
const float PI = 3.14159;
const float FencePrice = 35;
const float ConcretePrice = 20;
//声明类Circle 及其数据和方法
class Circle{
private:
float radius;
public:
Circle(float r); //构造函数
float Circumference() const; //圆周长
/函数后的修饰符const表示该成员函数的执行不会改变类的状态,也就是说不会修改类的数据成员。 /
float Area() const; //圆面积
};// 类的实现
// 构造函数初始化数据成员radius
Circle::Circle(float r)
{
radius=r;
}
// 计算圆的周长
float Circle::Circumference() const
{
return 2 PI radius;
}
// 计算圆的面积
float Circle::Area() const
{
return PI radius radius;
}
void main ()
{
float radius;
float FenceCost, ConcreteCost;

// 提示用户输入半径
cout<<"Enter the radius of the pool: ";
cin>>radius;// 声明 Circle 对象
Circle Pool(radius);
Circle PoolRim(radius + 3);//计算栅栏造价并输出
FenceCost=PoolRim.Circumference()*FencePrice;
cout<<"Fencing Cost is ¥"<<FenceCost<<endl;//计算过道造价并输出
ConcreteCost=(PoolRim.Area()-
Pool.Area())*ConcretePrice;
cout<<"Concrete Cost is ¥"<<ConcreteCost<<endl;

}

运行结果

Enter the radius of the pool: 10
Fencing Cost is ¥2858.85
Concrete Cost is ¥4335.39

转载于:https://blog.51cto.com/14209412/2365750

C++ 构造函数与析构函数相关推荐

  1. C++ 笔记(17)— 类和对象(构造函数、析构函数、拷贝构造函数)

    1. 构造函数 构造函数是一种特殊的函数(方法),在根据类创建对象时被调用.构造函数是一种随着对象创建而自动被调用的函数,它的主要用途是为对象作初始化. 构造函数的名称与类的名称是完全相同的,并且不会 ...

  2. php构造和析构方法,php5构造函数与析构函数实例

    自php5起,有了构造函数与析构函数. 这使得php更富有面向对象的魅力了. 在php4时,构造函数用的是与类同名的函数来进行构造这个动作. 例如: 复制代码 代码示例: /* * myclass.p ...

  3. 提高C++性能的编程技术笔记:构造函数和析构函数+测试代码

    对象的创建和销毁往往会造成性能的损失.在继承层次中,对象的创建将引起其先辈的创建.对象的销毁也是如此.其次,对象相关的开销与对象本身的派生链的长度和复杂性相关.所创建的对象(以及其后销毁的对象)的数量 ...

  4. c++, 派生类的构造函数和析构函数 , [ 以及operator=不能被继承 or Not的探讨]

    说明:文章中关于operator=实现的示例,从语法上是对的,但逻辑和习惯上都是错误的. 参见另一篇专门探究operator=的文章:<c++,operator=>http://www.c ...

  5. C++中的构造函数VS析构函数

    1.构造函数 类的构造函数是类的一种特殊的成员函数,它会在每次创建类的新对象时执行.构造函数的名称与类的名称的完全相同的,并且不会返回任何数据类型,也不会返回void.构造函数用于为某些成员变量设置初 ...

  6. 多继承的构造函数和析构函数

    //程序2:多继承的构造函数 与 析构函数 #include<iostream> using namespace std;class A { public: A() { cout<& ...

  7. c++ 构造函数析构函数 数据安全_C++知识点 16:构造函数和析构函数的语法

    #define _CRT_SECURE_NO_WARNINGS #include using namespace std;// 创建一个类( 类内包括: 2个构造函数,一个析构函数) class Pe ...

  8. 多重继承的构造函数和析构函数

    多重继承的构造函数和析构函数的执行顺序: //此处不做注释和说明了,看程序能读懂的 #include <iostream> using namespace std; class base1 ...

  9. C++中构造函数和析构函数

    [注]致力于将知识讲明白!不懂请留言! 构造函数 定义 它是一种特殊的方法.主要用来在创建对象时初始化对象, 即为对象成员变量赋初始值,总与new运算符一起使用在创建对象的语句中. 另外,一个类可以有 ...

  10. c++ map 析构函数_C++学习刷题6--C++类的使用:构造函数、析构函数和类的使用

    一.前言 本部分为C++语言刷题系列中的第4节,主要讲解这几个知识点:构造函数.析构函数和类的使用.欢迎大家提出意见.指出错误或提供更好的题目! 二.知识点讲解 由以前知识可知,类的实现中包含成员变量 ...

最新文章

  1. 哀悼!华人著名计算机科学家刘炯朗逝世,图灵奖得主姚期智为其得意门生
  2. 常用linux下网络相关命令
  3. Redis如何淘汰过期的keys
  4. Python应用实战-Clumper | dplyr式的Python数据操作包
  5. cxp文件查看 欧姆龙_欧姆龙PLC CXP编程软件外文手册
  6. JSESSIONID是什么
  7. 运用spss modeler运用支持向量机_使用支持向量回归进行Facebook股票预测
  8. matlab 图像处理之拟合圆
  9. python 爬取贝壳网小区名称_利用python爬取贝壳网租房信息,python爬虫接单网, 最近准备换房子,...
  10. 用ENSP配置ospf
  11. 基于python的百度离线地图下载器
  12. 查计算机主板,怎么查看自己电脑的主板型号是什么?主板型号查询检查方法
  13. 一款捕鱼手游分析 —— 实现无限购买金币
  14. 如何解决Kettle读取txt文件时出现的中文乱码问题?
  15. 使用aspose.word.for.java解析word文档图片并替换
  16. ubuntu20.04安装librtmp库 并在QT5中引入librtmp库
  17. android SDK buid tools 27.0.3版本离线下载
  18. Android即时通讯--仿QQ即时聊天:(一)初识Socket
  19. 服务器换主板不换系统教程,主板要换,系统不变
  20. 涉外诉讼公证认证北京代办流程时间

热门文章

  1. 集成学习 Ensemble Learing(???)
  2. tomcat使用自签名证书实现https加密访问
  3. LeetCode刷题(21)
  4. java接口自动化(一) - 接口自动化测试整体认知 - 开山篇(超详解)
  5. centos php open_basedir,CentOS 5服务器安全基本设置
  6. c语言五位数大到小排序,刚学c语言,老师让用if编一个五个数字从大到小的排序,有那个大神能帮我,谢谢啦...
  7. library的英语怎么读音_如何让你的英语口音无限接近母语者?英语语音语调的独家训练方法...
  8. linux+cd英文全称,Linux命令英文全称
  9. php处理post表单数据,php – Httpful post表单数据
  10. 英才计划计算机潜质测评试题,员工能力与素质测评题库完整.doc