note: look the sentence which have comments
当父类定义了一个函数,而子类也定义了一个同名的常函数,这时就会存在函数覆盖:
******illustrate********
#include <iostream.h>
class test
{
public:
void output()
{
cout<<"this is base"<<endl;
}
};
class member
{
public:
void greet()
{
cout<<"this is a member"<<endl;
}
};
class derive:public test
{
private:
member x;//because member have not parameters, so don't need constructor
public:
void output()
{
cout<<"this is a derive"<<endl;
x.greet();
}
};
int main()
{
derive de;
de.output();
de.test::output(); //if want to invoking the father class's function, must append the ::
return 0;
}
****the answer******
this is a derive
this is a member
this is base
now, we modify above programe, append the constructor
成员类和父类构造器的初始化,初始化父类时,使用的是类名,初始化成员类时,使用的是成员名
#include <iostream.h>
class test
{
private:
int x;
public:
test(int y)
{
x=y;
}
void output()
{
cout<<"this is base"<<endl;
}
};
class member
{
private:
float f1;
char ch;
public:
member(float f,char ch1)
{
f1=f;
ch=ch1;
}
void greet()
{
cout<<"this is a member"<<endl;
}
};
class derive:public test
{
private:
member x;//because member have not parameters, so don't need constructor
public:
derive(int x1,float y,char chr):test(x1),x(y,chr) //member class and parent class's initialize
{}
void output()
{
cout<<"this is a derive"<<endl;
x.greet();
}
};
int main()
{
derive de(45,12.32,'h');
de.output();
de.test::output();
return 0;
}
构造和析构的调用顺序
先是父类中的成员类的构造函数先调用,然后才是父类的构造函数,接下来就是子类,调用顺序相同,而析构相反。如果继承了多个类(多重继承),则按它们在定义派生类时的声明顺序有关。
*******illustrate***********
#include <iostream.h>
class member
{
public:
member()
{
cout<<"invoking the parent member constructor"<<endl;
}
~member()
{
cout<<"deconstruct"<<endl;
}
};
class test
{
private:
int x;
member xy;
public:
test(int y)
{
cout<<"parent constructor"<<endl;
x=y;
}
~test()
{
cout<<"the parent destruct"<<endl;
}
void output()
{
cout<<"this is base"<<endl;
}
};
class member1
{
private:
float f1;
char ch;
public:
member1(float f,char ch1)
{
f1=f;
ch=ch1;
}
void greet()
{
cout<<"this is a member"<<endl;
}
};
class derive:public test
{
private:
member1 x;//because member have not parameters, so don't need constructor
public:
derive(int x1,float y,char chr):test(x1),x(y,chr)
{cout<<"invoking the derive constructor"<<endl;}
~derive()
{
cout<<"the derive destruct "<<endl;
}
void output()
{
cout<<"this is a derive"<<endl;
x.greet();
}
};
int main()
{
derive de(45,12.32,'h');
de.output();
de.test::output();
return 0;
}
*********over*********
mapping up-----向上映射
we can use the above programe, define a new object
append the follow contents in main:
test te=derive(25,12.36,'a'); //this is mapping up
te.output();
注意:只有公有继承才能向上映射,private, protected不能向上映射
多重继承的二义性
例如:
class base1
{
void display()
{
cout<<"base1"<<endl;
}
};
class base2
{
void display()
{
cout<<"base2";
}
};
class derive:public base1,public base2
{
void output()
{
cout<<"the derive class"<<endl;
}
};
int main()
{
derive der;
der.display(); //现在这个语句就会出现二义性,不知调用父类的哪一个常函数,加上作用域就可以了
der.base1::display();
der.base2::display();// now, it can run rightly
return 0;
}
访问共同基类成员时的二义性
class base
{
public:
base()
{
cout<<"base constructor"<<endl;
}
void common()
{
cout<<"base"<<endl;
}
};
class base1:public base
{
public:
base1()
{
cout<<"base1.constructor"<<endl;
}
void display()
{
cout<<"base1"<<endl;
}
};
class base2:public base
{
public:
base2()
{
cout<<"base2.constructor"<<endl;
}
void display()
{
cout<<"base2";
}
};
class derive:public base1,public base2
{
public:
void output()
{
cout<<"the derive class"<<endl;
}
};
int main()
{
derive der;
//der.common(); //现在这个就会出现二义性,因为不知是通过哪个父类调用父类的父类
//解决办法,仍然是用作用域来解决。只不过会对父类有两次拷贝
der.base1::common();
return 0;}
******the result******
base constructor
base1.constructor
base constructor
base2.constructor
base
从以上结果可以看出,基类的构造函数被调用了两次。
*******虚基类*************
利用上面的程序,只需在继承自共同基类的派生类声明时显示地标明继承方式为虚拟(virtual)继承,其格式为:
<derived name>:<virtual><inherit mode><base name>
******illustrate**********
class base
{
public:
base()
{
cout<<"base constructor"<<endl;
}
void common()
{
cout<<"base"<<endl;
}
};
class base1:virtual public base
{
public:
base1()
{
cout<<"base1.constructor"<<endl;
}
void display()
{
cout<<"base1"<<endl;
}
};
class base2:virtual public base
{
public:
base2()
{
cout<<"base2.constructor"<<endl;
}
void display()
{
cout<<"base2";
}
};
class derive:public base1,public base2
{
public:
void output()
{
cout<<"the derive class"<<endl;
}
};
int main()
{
derive der;
der.common(); //现在这个就不会出现二义性
//der.base1::common();
return 0;}
the result:
base constructor
base1.constructor
base constructor
base2.constructor
base
从以上结果可以看出,父类的构造函数只调用了一次
虚基类的初始化
在虚拟继承中,必须在最晚派生类的构造函数中显式地调用虚基类的构造函数,其格式如下:
<the last derive class constructor><parameter list><direct base's constructor><member object constructor><virtual base class constructor>{define new append members }
*******illustrate*******
#include <iostream.h>
class base
{
private:
int i;
public:
base(int x)
{
i=x;
cout<<"base constructor"<<endl;
cout<<i<<endl;
}
int geti() const
{
return i;
}
void common()
{
cout<<"base"<<endl;
}
};
class base1:virtual public base
{
int y;
public:
base1(int w,int z):base(w)
{
y=z;
cout<<"base1.constructor"<<endl;
}
void display()
{
cout<<"base1"<<endl;
}
};
class base2:virtual public base
{private:
int aa;
public:
base2(int a, int b):base(b)
{
aa=a;
cout<<"base2.constructor"<<endl;
}
void display()
{
cout<<"base2";
}
int geti() const
{
return aa;
}
};
class derive:public base1,public base2
{
public:
derive(int a1,int a2,int a3,int a4):base1(a1,a2),base2(a3,a4),base(a4){}
//initialize the virtual base class constructor
void output()
{
cout<<"the derive class"<<endl;
}
};
int main()
{
derive der(12,25,34,45);
der.common(); //
//
//der.base1::common();
cout<<der.geti()<<endl;
return 0;}
当父类定义了一个函数,而子类也定义了一个同名的常函数,这时就会存在函数覆盖:
******illustrate********
#include <iostream.h>
class test
{
public:
void output()
{
cout<<"this is base"<<endl;
}
};
class member
{
public:
void greet()
{
cout<<"this is a member"<<endl;
}
};
class derive:public test
{
private:
member x;//because member have not parameters, so don't need constructor
public:
void output()
{
cout<<"this is a derive"<<endl;
x.greet();
}
};
int main()
{
derive de;
de.output();
de.test::output(); //if want to invoking the father class's function, must append the ::
return 0;
}
****the answer******
this is a derive
this is a member
this is base
now, we modify above programe, append the constructor
成员类和父类构造器的初始化,初始化父类时,使用的是类名,初始化成员类时,使用的是成员名
#include <iostream.h>
class test
{
private:
int x;
public:
test(int y)
{
x=y;
}
void output()
{
cout<<"this is base"<<endl;
}
};
class member
{
private:
float f1;
char ch;
public:
member(float f,char ch1)
{
f1=f;
ch=ch1;
}
void greet()
{
cout<<"this is a member"<<endl;
}
};
class derive:public test
{
private:
member x;//because member have not parameters, so don't need constructor
public:
derive(int x1,float y,char chr):test(x1),x(y,chr) //member class and parent class's initialize
{}
void output()
{
cout<<"this is a derive"<<endl;
x.greet();
}
};
int main()
{
derive de(45,12.32,'h');
de.output();
de.test::output();
return 0;
}
构造和析构的调用顺序
先是父类中的成员类的构造函数先调用,然后才是父类的构造函数,接下来就是子类,调用顺序相同,而析构相反。如果继承了多个类(多重继承),则按它们在定义派生类时的声明顺序有关。
*******illustrate***********
#include <iostream.h>
class member
{
public:
member()
{
cout<<"invoking the parent member constructor"<<endl;
}
~member()
{
cout<<"deconstruct"<<endl;
}
};
class test
{
private:
int x;
member xy;
public:
test(int y)
{
cout<<"parent constructor"<<endl;
x=y;
}
~test()
{
cout<<"the parent destruct"<<endl;
}
void output()
{
cout<<"this is base"<<endl;
}
};
class member1
{
private:
float f1;
char ch;
public:
member1(float f,char ch1)
{
f1=f;
ch=ch1;
}
void greet()
{
cout<<"this is a member"<<endl;
}
};
class derive:public test
{
private:
member1 x;//because member have not parameters, so don't need constructor
public:
derive(int x1,float y,char chr):test(x1),x(y,chr)
{cout<<"invoking the derive constructor"<<endl;}
~derive()
{
cout<<"the derive destruct "<<endl;
}
void output()
{
cout<<"this is a derive"<<endl;
x.greet();
}
};
int main()
{
derive de(45,12.32,'h');
de.output();
de.test::output();
return 0;
}
*********over*********
mapping up-----向上映射
we can use the above programe, define a new object
append the follow contents in main:
test te=derive(25,12.36,'a'); //this is mapping up
te.output();
注意:只有公有继承才能向上映射,private, protected不能向上映射
多重继承的二义性
例如:
class base1
{
void display()
{
cout<<"base1"<<endl;
}
};
class base2
{
void display()
{
cout<<"base2";
}
};
class derive:public base1,public base2
{
void output()
{
cout<<"the derive class"<<endl;
}
};
int main()
{
derive der;
der.display(); //现在这个语句就会出现二义性,不知调用父类的哪一个常函数,加上作用域就可以了
der.base1::display();
der.base2::display();// now, it can run rightly
return 0;
}
访问共同基类成员时的二义性
class base
{
public:
base()
{
cout<<"base constructor"<<endl;
}
void common()
{
cout<<"base"<<endl;
}
};
class base1:public base
{
public:
base1()
{
cout<<"base1.constructor"<<endl;
}
void display()
{
cout<<"base1"<<endl;
}
};
class base2:public base
{
public:
base2()
{
cout<<"base2.constructor"<<endl;
}
void display()
{
cout<<"base2";
}
};
class derive:public base1,public base2
{
public:
void output()
{
cout<<"the derive class"<<endl;
}
};
int main()
{
derive der;
//der.common(); //现在这个就会出现二义性,因为不知是通过哪个父类调用父类的父类
//解决办法,仍然是用作用域来解决。只不过会对父类有两次拷贝
der.base1::common();
return 0;}
******the result******
base constructor
base1.constructor
base constructor
base2.constructor
base
从以上结果可以看出,基类的构造函数被调用了两次。
*******虚基类*************
利用上面的程序,只需在继承自共同基类的派生类声明时显示地标明继承方式为虚拟(virtual)继承,其格式为:
<derived name>:<virtual><inherit mode><base name>
******illustrate**********
class base
{
public:
base()
{
cout<<"base constructor"<<endl;
}
void common()
{
cout<<"base"<<endl;
}
};
class base1:virtual public base
{
public:
base1()
{
cout<<"base1.constructor"<<endl;
}
void display()
{
cout<<"base1"<<endl;
}
};
class base2:virtual public base
{
public:
base2()
{
cout<<"base2.constructor"<<endl;
}
void display()
{
cout<<"base2";
}
};
class derive:public base1,public base2
{
public:
void output()
{
cout<<"the derive class"<<endl;
}
};
int main()
{
derive der;
der.common(); //现在这个就不会出现二义性
//der.base1::common();
return 0;}
the result:
base constructor
base1.constructor
base constructor
base2.constructor
base
从以上结果可以看出,父类的构造函数只调用了一次
虚基类的初始化
在虚拟继承中,必须在最晚派生类的构造函数中显式地调用虚基类的构造函数,其格式如下:
<the last derive class constructor><parameter list><direct base's constructor><member object constructor><virtual base class constructor>{define new append members }
*******illustrate*******
#include <iostream.h>
class base
{
private:
int i;
public:
base(int x)
{
i=x;
cout<<"base constructor"<<endl;
cout<<i<<endl;
}
int geti() const
{
return i;
}
void common()
{
cout<<"base"<<endl;
}
};
class base1:virtual public base
{
int y;
public:
base1(int w,int z):base(w)
{
y=z;
cout<<"base1.constructor"<<endl;
}
void display()
{
cout<<"base1"<<endl;
}
};
class base2:virtual public base
{private:
int aa;
public:
base2(int a, int b):base(b)
{
aa=a;
cout<<"base2.constructor"<<endl;
}
void display()
{
cout<<"base2";
}
int geti() const
{
return aa;
}
};
class derive:public base1,public base2
{
public:
derive(int a1,int a2,int a3,int a4):base1(a1,a2),base2(a3,a4),base(a4){}
//initialize the virtual base class constructor
void output()
{
cout<<"the derive class"<<endl;
}
};
int main()
{
derive der(12,25,34,45);
der.common(); //
//
//der.base1::common();
cout<<der.geti()<<endl;
return 0;}
作者:jackxiang@向东博客 专注WEB应用 构架之美 --- 构架之美,在于尽态极妍 | 应用之美,在于药到病除
地址:https://jackxiang.com/post/985/
版权所有。转载时必须以链接形式注明作者和原始出处及本声明!
评论列表