[C++]第八章第三节 构造函数(作业)
第四周作业
(
- *初学C++,想要把每周老师布置的实验题和自己写的程序记录下来,方便期末整理复习,请多多指教!
- 老师要求用的版本比较老,是Microsoft Visual C++ 2010 Express。
)
这周学了构造函数,于是老师布置的作业就是把上周的两个题目用构造函数重新写一遍
啦啦啦
一,知识点
1.引入构造函数
构造函数用于对象的初始化(分配内存空间),当某个对象使用结束时,通过析构函数(下周应该会学)来做一些善后工作。
在C++中,变量、数组、结构体和指针等在定义时,都可以用直接列表对其初始化,即在赋值号右边放置值的列表。
但是类的成员复杂,在定义类对象时,一般不能用上述方式对对象初始化。
引入了构造函数,类对象的初始化问题就迎刃而解了。构造函数可以保护类的私有成员和保护成员。
对象的初始化有三种方法:
- 初始化列表,类似于上述例子中的A行;
- 构造函数,下面详细讨论;
- 拷贝构造函数,也称复制构造函数。
2.构造函数的定义与使用
在类内定义构造函数的一般格式为:
ClassName(<形参表>)
{…}
在类外定义构造函数的一般格式为:
ClassName::ClassName(<形参表>)
{…}
例:类的构造函数
class TDate
{public:
TDate(int y, int m, int d)//构造函数
{ year = y; month = m; day = d; }
void Print() //在类内定义
{ cout<<year<<"."<<month
cout<<"."<<day<<endl;
}
private:
int year, month, day;
};
3.构造函数的特点:
1.函数名特点。构造函数的函数名必须与类名相同。构造函数的主要作用是完成初始化对象的数据成员以及其它的初始化工作。
2.返回值特点。在定义构造函数时,不能指定函数返回值的类型,也不能指定为void类型。
3.重载特点。一个类可以定义若干个构造函数。当定义多个构造函数时,必须满足函数重载的原则。
4.缺省值特点。构造函数可以指定参数的缺省值。
5.访问属性特点。类的构造函数为公有时,该类既可以定义对象也可以派生。
==类的构造函数为保护时,该类仅可以用于派生;
- 类的构造函数一般为公有成员;
- 类的构造函数为保护时,该类仅可以用于派生;
- 类的构造函数为私有时,该类既不可以定义对象,也不可以用于派生。
例:调用缺省构造函数错误的例子。
#include<iostream.h>
class M
{ int x;
public:
M(){ x=0; }
void display(){ cout<<"x="<<x<<endl; }
};
void main()
{ M a();
a.display();
}
错误!
这里是一个返回值为M类对象的函数声明,不是定义对象
4.默认构造函数
在C++中把没有参数或者参数都有默认值的构造函数称为默认构造函数。
-
如果在程序中不显式提供构造函数,编译器会自动产生一个公共的默认构造函数。
-
如果至少提供一个构造函数,则编译器就不会产生默认构造函数。
默认的构造函数的形式为: ClassName() { }
例:使用一个全部参数都有默认值的构造函数定义所有对象。
class Sample
{ int x,y,z;
public:
Sample(int a=0,int b=1,int c=2)
{ x=a;y=b;z=c;}
void disp()
{ cout<<x<<‘\t’<<y<<‘\t’<<z<<endl; }
};
void main()
{ Sample a, b(1), c(10,20), d(5,6,7); }
5.对象分局部对象、静态对象、全局对象等几种,他们的初始化有所不同。
- 对于函数中的局部对象,每次调用函数时都定义对象,都要调用构造函数。
- 对于==(局部)静态对象==,是在首次调用函数时定义对象,调用构造函数。且由于对象一直存在,只调用一次构造函数。
- 对于全局对象,是在main函数执行之前调用构造函数的。
例:定义复数类及三种对象
class complex{
float r, i;
public:
complex(float a, float b)
{ r=a; i=b; cout<<"自动局部对象\n";}
complex()
{ r=0; i=0; cout<<"静态局部对象\n";}
complex(float a)
{ r=a; i=0; cout<<"全局对象\n"; }
void Print(void){ cout<<r<<'\t'<<i<<endl; }
};
complex c1(100.0); //定义全局对象
void f( )
{ cout<<"进入f()函数\n";
complex c2(1,2);
static complex c3;
}
void main()
{ cout<<"进入main函数\n";
f();
complex c4(2, 8);
f();
}
输出结果:
全局对象
进入main函数
进入f()函数
自动局部对象
局部静态变量
自动局部对象
进入f()函数
自动局部对象
二,题目
1.定义图书类
设图书信息包括书名、作者、出版社和定价等属性,要求定义一个类 ,用该类定义图书对象、通过函数成员为对象数据成员赋值,能输出图书属性。
#include<string.h>
using namespace std;
class Book
{
private:
char Name[50],Auth[50],Press[50];
double Price;
public:
Book(char *name,char *auth,char *press,double price);
void Display();
};
Book::Book(char *name,char *auth,char *press,double price)
{
strcpy(Name,name);strcpy(Auth,auth);
strcpy(Press,press);Price=price;
}
void Book::Display()
{
cout<<Name<<'\t'<<Auth<<'\t'<<Press<<endl;
cout<<" 单价为"<<Price<<endl;
}
void main(void)
{
char a[40]="《追风筝的人》",b[40]="卡勒德·胡赛尼",c[40]="上海人民出版社";
double price=27.6;
Book b1(a,b,c,price);
b1.Display();
getchar();
getchar();
}
2.定义商品类
设商品包括下列属性:商品名(字符串)、单价(实型)、数量(实型)和金额(实型)。商品的商品名和单价属性在定义商品时给定。考虑商品的销售情况,对于某个已定义的商品,给定其数量,应能自动计算出金额。
/*设商品包括下列属性:商品名(字符串)、单价(实型)、数量(实型)和
金额(实型)。商品的商品名和单价属性在定义商品时给定。考虑商品的
销售情况,对于某个已定义的商品,给定其数量,应能自动计算出金额。*/
#include<iostream>
using namespace std;
class item
{
char Name[50];
double Price,Mony;
public:
double S;
item(char *a,double b);
void sum(double c)
{
S=Price*c;
}
};
item::item(char *a,double b)
{
strcpy(Name,a);
Price=b;
}
void main()
{
char a[10]="牛奶";
double b,n,s;
cout<<"请输入商品的单价和数量:"<<endl;
cin>>b>>n;
item a1(a,b);
a1.sum(n);
cout<<"总价是:"<<a1.S<<endl;
getchar();
getchar();
}