第八章答案
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
{
b=sb;
cout<<"Constructing base1"<<endl;
}
};
class base2:virtual public base
{
int c;
public:
base2(int sa, int sc):base(sa)//初始化列表
{
c=sc;
cout<<"Constructing base2 "<<endl;
4
#include<iostream.h>
class base
{
int a;
public:
base(int sa)
{
a=sa;
cout<<"Constructing base"<<endl;
}
};
class base1:virtual public base
{
int b;
public:
base1(int sa, int sb):base(sa)//初始化列表
};
class B2
{
public:
B2(int j){cout<<"constructing B2 "<<j<<endl;}
};
class B3
{
public:
B3(){cout<<"constructing B3 *"<<endl;}
};
class C: public B2,public B1,public B3//按继承顺序调用构造函数
{
B1::print();//::作用域运算符确定执行哪一个类的成员函数
B2::print();
cout<<a<<","<<bb.getb3()<<endl;
}
private:
int a;
B3 bb;//类B3的对象作为类A的私有成员对象
};
void main()
{
A aa(1,2,3,4);
aa.print();
#include<iostream.h>
class B0
{
public:
void display()
{cout<<"B0::display()"<<endl;};
};
class B1:public B0
{
public:
void display(){cout<<"B1::display()"<<endl;}
{
public: C(int a, int b, int c, int d): B1(a), memberB2(d),memberB1(c),B2(b){}
private:
B1 memberB1;//按对象定义顺序调用构造函数
B2 memberB2;
B3 memberB3;
};
void main()
fun(p);
p=&b1;
fun(p);
p=&d1;
fun(p);
}
运行结果:
B0::display()
B0::display()
B0::display()
结论:用派生类对象的地址给指向基类的对象的指针赋值,然后通过指针调用同名成员函数,只能调用基类的同名成员函数。
{
b3=i;
cout<<"constructor B3"<<i<<endl;
}
void print()
{
cout<<b3<<endl;
}
int getb3(){return b3;}
private:
int b3;
};
class A:public B2, public B1/*基类构造函数按B2,B1顺序执行,A为基类B2和基类B1的多继承派生类*/
第8讲课堂练习解答
1
#include<iostream.h>
class B1
{
public:
B1(int i)//基类B1构造函数
{
b1=i;
cout<<"constructor B1"<<i<<endl;
}
void print()
{
cout<<b1<<endl;
}
private:
int b1;
};
{
public:
base2()
{
cout<<"base2 a="<<a<<endl;
}
};
class derived:public base1,public base2
{
public:
derived()
{
cout<<"derived a="<<a<<endl;//error可改为base2::a或base1::a
}
};
int main()
{
derived obj;
return 0;
}
注意到base1和base2是从同一个基类base的派生类,基类base成员a在base1和base2中存在两个不同的拷贝,即base1中的a和base2中的a是不同类的成员。而derived又是base1和base2的派生类,那么,在建立对象obj调用类derived的构造函数时,是访问base1中的a还是base2中的a?这就是所谓的二义性问题。
}
};
main()
{
derived obj(2,4,6,8);
return 0;
};
运算结果:
Constructing base
Constructing base1
Constructing base2
Constructing derived
注意:虚基类构造函数带有参数时,直接派生类和间接派生类的构造函数都必须带有对虚基类构造函数的调用。
{
public:
int nV;
void fun(){cout<<"Member of D1"<<endl;}
};
void main()
{
D1 d1;
d1.nV=1;//写出为D1的nV赋值1的表达式语句
d1.fun();//写出调用D1的fun()的表达式语句
d1.B1::nV=2;//写出为B1的nV赋值2的表达式语句
d1.B1::fun();//写出调用B1的fun()的表达式语句
d1.B2::nV=3;//写出为B2的nV赋值2的表达式语句
d1.B2::fun();//写出调用B2的fun()的表达式语句
}
运行结果:
Member of D1
Member of B1
Member of B2
6
阅读并运行下面程序,根据运行结果,得出结论。
};
class D1:public B1
{
public:
void display(){cout<<"D1::display()"<<endl;}
};
void fun(B0 *prt)
{
prt->display();
}
void main()
{
B0 b0;
B1 b1;
D1 d1;
B0 *p;
p=&b0;
}
};
class derived:public base1,public base2
{
int d;
public:
derived(int sa, int sb, int sc, int sd):
base(sa),base1(sa,sb),base2(sa,sc)//初始化列表
{
d=sd;
cout<<"Constructing derived "<<endl;
}
运行结果:
constructor B22
constructor B11
constructor B33
constructor A.4
1
2
4,3
2
阅读并运行下面程序,根据运行结果,得出构造函数执行顺序的结论。
#include<iostream.h>
class B1
{
public:
B1(int i){cout<<"constructing B1 "<<i<<endl;}
class B2
{
public:
B2(int i)//基类B2构造函数
{
b2=i;
cout<<"constructor B2"<<i<<endl;
}
void print()
{
cout<<b2<<endl;
}wk.baidu.com
private:
int b2;
};
class B3
{
public:
B3(int i) //基类B3构造函数
3
#include<iostream.h>
class base
{
protected:
int a;
public:
base()
{
a=5;
}
};
class base1:public base
{
public:
base1()
{
cout<<"base1 a="<<a<<endl;
}
};
class base2:public base
{
C obj(1,2,3,4);
}
运行结果:
constructing B2 2
constructing B1 1
constructing B3 *
constructing B1 3
constructing B2 4
constructing B3 *
程序的主函数只是定义了一个派生类C的对象c,生成对象c时调用了派生类的构造函数。它应该先调用基类的构造函数。然后调用成员对象的构造函数。基类构造函数的调用顺序是按照派生类声明时的顺序。因此应该是先B2,再B1,再B3。而成员对象的调用顺序是按照成员在类中声明的顺序,应该是先B1,再B2,再B3。
{
public:
A(int i,int j,int k,int l):B1(i),B2(j),bb(k)/*在派生类A的构造函数的成员初始化列表中,将参数传给基类构造函数B1(i),B2(j)和类B3的对象bb*/
{
a=l;
cout<<"constructor A."<<l<<endl;
}
void print()
5
#include<iostream.h>
class B1
{
public:
int nV;
void fun(){cout<<"Member of B1"<<endl;}
};
class B2
{
public:
int nV;
void fun(){cout<<"Member of B2"<<endl;}
};
class D1:public B1,public B2 //声明派生类D1
b=sb;
cout<<"Constructing base1"<<endl;
}
};
class base2:virtual public base
{
int c;
public:
base2(int sa, int sc):base(sa)//初始化列表
{
c=sc;
cout<<"Constructing base2 "<<endl;
4
#include<iostream.h>
class base
{
int a;
public:
base(int sa)
{
a=sa;
cout<<"Constructing base"<<endl;
}
};
class base1:virtual public base
{
int b;
public:
base1(int sa, int sb):base(sa)//初始化列表
};
class B2
{
public:
B2(int j){cout<<"constructing B2 "<<j<<endl;}
};
class B3
{
public:
B3(){cout<<"constructing B3 *"<<endl;}
};
class C: public B2,public B1,public B3//按继承顺序调用构造函数
{
B1::print();//::作用域运算符确定执行哪一个类的成员函数
B2::print();
cout<<a<<","<<bb.getb3()<<endl;
}
private:
int a;
B3 bb;//类B3的对象作为类A的私有成员对象
};
void main()
{
A aa(1,2,3,4);
aa.print();
#include<iostream.h>
class B0
{
public:
void display()
{cout<<"B0::display()"<<endl;};
};
class B1:public B0
{
public:
void display(){cout<<"B1::display()"<<endl;}
{
public: C(int a, int b, int c, int d): B1(a), memberB2(d),memberB1(c),B2(b){}
private:
B1 memberB1;//按对象定义顺序调用构造函数
B2 memberB2;
B3 memberB3;
};
void main()
fun(p);
p=&b1;
fun(p);
p=&d1;
fun(p);
}
运行结果:
B0::display()
B0::display()
B0::display()
结论:用派生类对象的地址给指向基类的对象的指针赋值,然后通过指针调用同名成员函数,只能调用基类的同名成员函数。
{
b3=i;
cout<<"constructor B3"<<i<<endl;
}
void print()
{
cout<<b3<<endl;
}
int getb3(){return b3;}
private:
int b3;
};
class A:public B2, public B1/*基类构造函数按B2,B1顺序执行,A为基类B2和基类B1的多继承派生类*/
第8讲课堂练习解答
1
#include<iostream.h>
class B1
{
public:
B1(int i)//基类B1构造函数
{
b1=i;
cout<<"constructor B1"<<i<<endl;
}
void print()
{
cout<<b1<<endl;
}
private:
int b1;
};
{
public:
base2()
{
cout<<"base2 a="<<a<<endl;
}
};
class derived:public base1,public base2
{
public:
derived()
{
cout<<"derived a="<<a<<endl;//error可改为base2::a或base1::a
}
};
int main()
{
derived obj;
return 0;
}
注意到base1和base2是从同一个基类base的派生类,基类base成员a在base1和base2中存在两个不同的拷贝,即base1中的a和base2中的a是不同类的成员。而derived又是base1和base2的派生类,那么,在建立对象obj调用类derived的构造函数时,是访问base1中的a还是base2中的a?这就是所谓的二义性问题。
}
};
main()
{
derived obj(2,4,6,8);
return 0;
};
运算结果:
Constructing base
Constructing base1
Constructing base2
Constructing derived
注意:虚基类构造函数带有参数时,直接派生类和间接派生类的构造函数都必须带有对虚基类构造函数的调用。
{
public:
int nV;
void fun(){cout<<"Member of D1"<<endl;}
};
void main()
{
D1 d1;
d1.nV=1;//写出为D1的nV赋值1的表达式语句
d1.fun();//写出调用D1的fun()的表达式语句
d1.B1::nV=2;//写出为B1的nV赋值2的表达式语句
d1.B1::fun();//写出调用B1的fun()的表达式语句
d1.B2::nV=3;//写出为B2的nV赋值2的表达式语句
d1.B2::fun();//写出调用B2的fun()的表达式语句
}
运行结果:
Member of D1
Member of B1
Member of B2
6
阅读并运行下面程序,根据运行结果,得出结论。
};
class D1:public B1
{
public:
void display(){cout<<"D1::display()"<<endl;}
};
void fun(B0 *prt)
{
prt->display();
}
void main()
{
B0 b0;
B1 b1;
D1 d1;
B0 *p;
p=&b0;
}
};
class derived:public base1,public base2
{
int d;
public:
derived(int sa, int sb, int sc, int sd):
base(sa),base1(sa,sb),base2(sa,sc)//初始化列表
{
d=sd;
cout<<"Constructing derived "<<endl;
}
运行结果:
constructor B22
constructor B11
constructor B33
constructor A.4
1
2
4,3
2
阅读并运行下面程序,根据运行结果,得出构造函数执行顺序的结论。
#include<iostream.h>
class B1
{
public:
B1(int i){cout<<"constructing B1 "<<i<<endl;}
class B2
{
public:
B2(int i)//基类B2构造函数
{
b2=i;
cout<<"constructor B2"<<i<<endl;
}
void print()
{
cout<<b2<<endl;
}wk.baidu.com
private:
int b2;
};
class B3
{
public:
B3(int i) //基类B3构造函数
3
#include<iostream.h>
class base
{
protected:
int a;
public:
base()
{
a=5;
}
};
class base1:public base
{
public:
base1()
{
cout<<"base1 a="<<a<<endl;
}
};
class base2:public base
{
C obj(1,2,3,4);
}
运行结果:
constructing B2 2
constructing B1 1
constructing B3 *
constructing B1 3
constructing B2 4
constructing B3 *
程序的主函数只是定义了一个派生类C的对象c,生成对象c时调用了派生类的构造函数。它应该先调用基类的构造函数。然后调用成员对象的构造函数。基类构造函数的调用顺序是按照派生类声明时的顺序。因此应该是先B2,再B1,再B3。而成员对象的调用顺序是按照成员在类中声明的顺序,应该是先B1,再B2,再B3。
{
public:
A(int i,int j,int k,int l):B1(i),B2(j),bb(k)/*在派生类A的构造函数的成员初始化列表中,将参数传给基类构造函数B1(i),B2(j)和类B3的对象bb*/
{
a=l;
cout<<"constructor A."<<l<<endl;
}
void print()
5
#include<iostream.h>
class B1
{
public:
int nV;
void fun(){cout<<"Member of B1"<<endl;}
};
class B2
{
public:
int nV;
void fun(){cout<<"Member of B2"<<endl;}
};
class D1:public B1,public B2 //声明派生类D1