C++疑难问题自测

myan 2001-01-12 10:23:00
// 不知什么时候从网上当下来的, 翻译成中文, 大家自己测试一把

1. 为什么Scott Meyers说最好把基类的析构函数定义为virtual的?

2. 有一个类A, 定义了缺省构造函数A::A(), 复制构造函数A::A(const A& copy) , 并且
重载了赋值操作A& A::operator=(const A& assign). 那么有下面的语句:
1: A a;
2: A b = a;
请问: 在执行第2行构造对象b时, 是直接执行复制构造函数A::A(const A& copy)还是
先用A::A()生成缺省对象b, 然后再调用A::operator=()来完成对b的构造?

3. 如果基类是模板类, 能否派生非模板类(常规类)? 非模板基类能否派生模板类? 从模板类
派生模板类, 对于模板参数有什么要求? 换句话说, 派生摸板类的模板参数必须跟基类模
板参数一致吗? 如果不是, 相应的规则是什么呢?

4. TA是一个模板类, 现在想写一个模板类TB, 从TA中公有派生出来, TB的声明语法是怎样的?

5. 假如有:
class RA;
...
class RB : public RA;
...

template < typename T >
class TA {
...
}

template < typename T >
class TB : public TA<T> { // 这就是第4题的答案
...
}

请问TB<int>是不是TA<float>的派生类? TB<RB>是不是TA<RA>的派生类? (注意: TB是TA的派生类,
RB是RA的派生类, 也就是说模板类本身和模板参数都存在继承关系).

6. 模板类中定义的成员函数, 通常只有在被调用时才会被实际编译, 这样可以缩小执行文件的体积,
加快编译速度. 但是虚成员函数例外, 模板类中的虚成员函数不论是否被调用, 必须被一律编译,
请解释Stroustrup这个设计的道理何在.

7. 实例化派生模板类会不会导致基类模板类也同时被实例化?

8. 请解释以下C++关键字:
mutable, reinterpret_cast, dynamic_cast, typename, typeid

9. 有一个类my_ptr, 模拟指针的行为, 于是重载了operator*() 和operator->(). 它有一个数据成员
_target, 指向实际的目标对象. 设计时希望对my_ptr的*和->操作能够由_target的*和->操作来实
际完成, 请问在operator*()应该如何实现, 是return *_target还是return _target?
operator->()中呢?

10. class A {
void member_func();
void member_func() const;
...
};

在上面的例子中, 两个member_func()的参数表和返回指都一样, 只不过一个是const的, 另一个不
是. 两者是否构成重载? 如果确实构成重载, 如何判断A_obj.member_func()调用的是哪一个呢?

// 还有一些, 以后再说
...全文
345 10 打赏 收藏 举报
写回复
10 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
cber 2001-01-29
第7题:
会,根据C++对象模型,派生类中有一个基类的subobject存在,如果不实例化基类,则得不到正确的C++对象模型。
第6题:
因为虚函数的调用是通过vptr及vtbl来调用的,在编译时,虚函数的入口地址按其宣告顺序放入vtbl中(以1为起始偏移,0被保存用于typeid),如果不编译所有的虚函数的话,则得不到正确的虚函数的入口地址。
  • 打赏
  • 举报
回复
wao 2001-01-28
问题6:
因为编译程序编译时刻无法知道是否调用了虚函数,所以全部编译。而普通成员函数是在编译时刻确定是否调用过的,所以可以加以优化。
  • 打赏
  • 举报
回复
wao 2001-01-27
第9题:
A& operator*()
{
return *_target;
}

A* operator->()
{
return _target;
}
  • 打赏
  • 举报
回复
cber 2001-01-27
第10题:
构成重载,有const修饰的函数只能被const object调用,即如果A_obj是一个const object,那么A_obj.member_func()调用的是有const修饰的那个
第8题补充:
reinterpret_cast在ANSI C++标准中的定义是implementation-defined,即它不具有可移植性,一般大家都使用它来进行函数指针的转型
typename的确切意思是告诉编译器后续的标示符是指一个类型的名字,这一点在模版实例化时特别有用
  • 打赏
  • 举报
回复
yanxb 2001-01-21
关注!
  • 打赏
  • 举报
回复
hyqryq 2001-01-21
第一个问题的答案:
将析构定义成virtual的是可以正确析构.
第二个问题的答案:
先用A::A()生成缺省对象b, 然后再调用A::operator=()来完成对b的构造.
若用b(a),则执行复制构造函数A::A(const A& copy).因为=被重载了.
第三个问题的答案:
都可以.派生摸板类的模板参数不一定跟基类模板参数一致.分为开放型,
封闭型和混合型.
第四个问题的答案:
class TB : public TA<T>
第五个问题的答案:
不是.

好难呀!先回答到这里,答案不一定对,望大家多多指教! (^-^)







  • 打赏
  • 举报
回复
cber 2001-01-21
mutable用于class中的member data,是为了避免将一个class产生的const object中的所有member data都自动获得const属性,如果一个member data被声明为mutable,则即使产生一个class的const object,这个const object中的该member data还是可以被改动的, 即它没有被const保护
reinterpret_cast的意思我现在有点忘了,得回家查书才能给你一个确切的答案(我不想乱说影响他人)
dynamic_cast是用于自动转型时使用的关键字,他提供了一定的类型判断能力,对于不匹配的类型转换,将会提出一些出错信息,这一点不同于以往C的强制转型
typename用于template中,这时候等于class(不是类的意思),他还有另一个意思,不过我现在也记得不太清楚,等以后再告诉你,
typeid严格来讲不是一个关键字,他只是一个类名,用来纪录object的类型信息

还有,你一次问的问题太多了,我得分几次才能回答完,今天先给出8的回答,其他的以后再说(估计在年后)
  • 打赏
  • 举报
回复
babysloth 2001-01-20
3.都可以.
class A{

};
template <class T> class B:public A{
public:
T b;
};
template <class T> class C:public B<T>{};
class D:public C<int>
{
};
  • 打赏
  • 举报
回复
babysloth 2001-01-20
2.如果是A b=a;就调用复制构造,如果是
A b;
b=a;
才先用A::A()生成缺省对象b, 然后再调用A::operator=().
  • 打赏
  • 举报
回复
darkay 2001-01-20
谁能将你们的看法说来看看,我只确切知道第一个问题的答案
1.将析构定义成virtual的是可以正确析构,例如下面的情况可以正确的调用B的析构函数,如果没有定义virtual的话,它将调用A的析构函数。
class A{...}
class B:public A{...}
...
{
B *b = new B;
A *a;
a = b;
delete a;
}
  • 打赏
  • 举报
回复
相关推荐
发帖
非技术区
加入

1.5w+

社区成员

C/C++ 非技术区
社区管理员
  • 非技术区社区
申请成为版主
帖子事件
创建了帖子
2001-01-12 10:23
社区公告
暂无公告