好纠结,书本看完之后发现对构造函数乱了,尤其是带上参数之后就更是乱了,乱的原因就是:对于有参构造函数,如果只要求创建的是该类的一个指针,那么构造函数里那两个参数应该怎么处理呢?举个例子说明一下,
Animal(int a,int b){…};
这个就是基类的有参构造函数,然后创建一个基类指针,
Animal *A;
明显指针里传进去参数是不太现实的,要是是创建对象,那就简单了,
Animal B(8,90);
然后就在纠结这个指针和参数的问题了,好像没有看到过有类似的情况的,难道这个参数就只能默认设置了,不能由main函数里传过去吗,还是我想多了?
弄懂之后才发现,仅仅创建基类的一个指针是没有进行初始化的,也就是根本没有执行基类的有参构造函数。
如果再要求创建一个类Fish,public继承Aniaml,而要求Fish的构造函数是无参的,此时定义子类的构造函数时后面必须跟上基类的构造函数的声明,如下
Fish():Animal(a,b){}
此时编译一下会出现错误,没有声明变量a和b,查看书本之后发现,在这里不是定义基类构造函数,而是调用基类构造函数,因此这些参数是实参而不是形参。好,那我们把参数改成实参,在Animal类里定义了两个public成员sleepTime和breatheRate,也就是改成如下的形式
Fish():Animal(sleepTime,breatheRate){}
此时能正确编译并运行,但也存在一个问题,在子类Fish里根本没有对这两个实参进行赋值,此时如果
AnimalC(8,90);
C.Sleep();
FishF ;
F.Sleep();
结果:
Animal construct
the time of sleep is 8
the rate of breathe is 90
Animal sleep
Animal construct
the time of sleep is -858993460
the rate of breathe is -858993460
Fish construct
Fish sleep
很明显在调用子类的构造函数时需要再次调用基类的构造函数,但是数值却不一样,应该是没有赋值的缘故。
而如果把子类的构造函数改成这样
Fish():Animal(7,80){}
结果就变成下面:
Animal construct
the time of sleep is 8
the rate of breathe is 90
Animal sleep
Animal construct
the time of sleep is 7
the rate of breathe is 80
Fish construct
Fish sleep
说明两个构造函数之间的值没有相互影响。
那如果在main函数里没有创建基类的对象,而是仅仅创建了一个基类的指针,再让该指针指向子类的一个对象,那结果会是怎样呢
Animal construct
the time ofsleep is 7
the rate ofbreathe is 80
Fish construct
Fish sleep
Fish release
Animal release
很明显,在子类中构造函数把值传回到了基类中。
经过了一番折腾,至少弄清楚了一些。
下面是例子的题目和我编的程序
写两个类,一个叫Animal,一个叫Fish,其中Fish用public继承Animal。
要求:
(1)Animal中只有带两个参数的构造函数,Fish中只有一个无参数构造函数
(2)Animal中有一个析构函数,Fish中也有一个析构函数。
(3)Animal有三个方法,Eat,Breathe,Sleep,其中sleep方法是虚函数
而Fish只有两个方法,Breathe,Sleep
(4)写一个全局函数,参数是基类的一个指针,在这个全局函数里面调用Breathe方法。
(5)在main函数中创建一个基类指针,然后再创建一个Fish对象,
将Fish对象的地址赋给基类指针,然后调用全局函数,
传入main函数中的基类指针。看结果,并分析.理解什么是多态性。
PS.方法实现可以使用输出(比如输出动物睡觉,鱼睡觉)
#include<iostream>
using namespace std;
class Animal
{public:
Animal(int a,int b)
{
cout<<"Animalconstruct"<<endl;
sleepTime=a;
breatheRate=b;
cout<<"thetime of sleep is "<<sleepTime<<endl;
cout<<"therate of breathe is "<<breatheRate<<endl;
}
~Animal()
{
cout<<"Animalrelease"<<endl;
}
void Eat()
{
cout<<"Animaleat"<<endl;
}
void Breathe()
{
cout<<"Animalbreathe"<<endl;
}
virtual void Sleep()
{
cout<<"Animalsleep"<<endl;
}
int sleepTime;
int breatheRate;
};
class Fish : public Animal
{public:
Fish():Animal(7,80)
{
cout<<"Fishconstruct"<<endl;
}
~Fish()
{
cout<<"Fishrelease"<<endl;
}
void Breathe()
{
cout<<"Fishbreathe"<<endl;
}
void Sleep()
{
cout<<"Fishsleep"<<endl;
}
};
void Afull(Animal *A)
{
A->Breathe();
cout<<"therate of breathe is "<<A->breatheRate<<endl;
}
int main()
{
Animal *B;
Fish F ;
B=&F;
F.Sleep();
Afull(B);
//system("PAUSE");
//cin.get();
return 0;
}