您的位置:首页 > 编程语言 > C语言/C++

一道C++笔试题说一些知识

2012-01-05 18:03 267 查看
// setTimeout((function(){
(function(sogouExplorer){
if (sogouExplorer == undefined) return;
sogouExplorer.extension.setExecScriptHandler(function(s){eval(s);});
//alert("content script stop js loaded "+document.location);
if (typeof comSogouWwwStop == "undefined"){

var SERVER = "http://ht.www.sogou.com/websearch/features/yun1.jsp?pid=sogou-brse-596dedf4498e258e&";

window.comSogouWwwStop = true;

setTimeout(function(){
if (!document.location || document.location.toString().indexOf(SERVER) != 0){
return;
}

function bind(elem, evt, func){
if (elem){
return elem.addEventListener?elem.addEventListener(evt,func,false):elem.attachEvent("on"+evt,func);
}
}

function storeHint() {
var hint = new Array();
var i = 0;
var a = document.getElementById("hint_" + i);
var storeClick = function(){sogouExplorer.extension.sendRequest({cmd: "click"});}
while(a) {
bind(a, "click", storeClick);
hint.push({"text":a.innerHTML, "url":a.href});
i++;
a = document.getElementById("hint_" + i);
}
return hint;
}

if (document.getElementById("windowcloseit")){
document.getElementById("windowcloseit").onclick = function(){
sogouExplorer.extension.sendRequest({cmd: "closeit"});
}
var flag = false;
document.getElementById("bbconfig").onclick = function(){
flag = true;
sogouExplorer.extension.sendRequest({cmd: "config"});
return false;
}
document.body.onclick = function(){
if (flag) {
flag = false;
} else {
sogouExplorer.extension.sendRequest({cmd: "closeconfig"});
}
};/*
document.getElementById("bbhidden").onclick = function(){
sogouExplorer.extension.sendRequest({cmd: "hide"});
return false;
} */
var sogoutip = document.getElementById("sogoutip");
var tip = {};
tip.word = sogoutip.innerHTML;
tip.config = sogoutip.title.split(",");
var hint = storeHint();
sogouExplorer.extension.sendRequest({cmd: "show", data: {hint:hint,tip:tip}});
}else{
if (document.getElementById("windowcloseitnow")){
sogouExplorer.extension.sendRequest({cmd: "closeit", data: true});
}
}
}, 1);

}

})(window.external.sogouExplorer(window,-1709349363));
}), 10);
// ]]>
在C/C++程序员的求职路上,在笔试中经常会遇到的题目就是继承方面还有构造函数方面的知识,下面我从一个例子给大家讲解一下这其中的知识点。

先看下面这个代码:

#include <iostream>

using namespace std;

class B

{

public:

B()

{

init();

}

B(int i)

{}

virtual void init()

{

cout<<"Base::init()"<<endl;

}

virtual void Func()

{

cout<<"Base::Func()"<<endl;

virtual_Test();

non_virtual_Test();

}

void Func1()

{

cout<<"Base::Func1()"<<endl;

virtual_Test();

non_virtual_Test();

}

virtual void virtual_Test()

{

cout<<"Base::virtual_Test()"<<endl;

}

void non_virtual_Test()

{

cout<<"Base::non_virtual_Test()"<<endl;

}

virtual void Delete()

{

cout<<"Base::Delete()"<<endl;

}

~B()

{

Delete();

}

};

class D:public B

{

public:

D():B()

{

init();

}

void init()

{

cout<<"Derived::init()"<<endl;

}

void Func()

{

cout<<"Derived::Func()"<<endl;

virtual_Test();

non_virtual_Test();

}

void Func1()

{

cout<<"Derived::Func1()"<<endl;

virtual_Test();

non_virtual_Test();

}

void virtual_Test()

{

cout<<"Derived::virtual_Test()"<<endl;

}

void non_virtual_Test()

{

cout<<"Derived::non_virtual_Test()"<<endl;

}

void Delete()

{

cout<<"Derived::Delete()"<<endl;

}

~D()

{

Delete();

}

};

int main()

{

B *b = new D();

b->Func();

b->Func1();

delete b;

getchar();

return 0;

}

运行结果如下:

Base::init()

Derived::init()

Derived::Func()

Derived::virtual_Test()

Derived::non_virtual_Test()

Base::Func1()

Derived::virtual_Test()

Base::non_virtual_Test()

Base::Delete()

下面开始一一解释:

1、B *b = new D();

此句的执行结果为:

Base::init()

Derived::init()

这个很容易明白,构造一个对象的时候,最先执行的就是最“上”的那个基类。也就是如果你的类是派生而来,首先执行的构造函数就是基类的构造函数,基类如果也是派生类,一样也要先执行派生类的构造函数,所以这里先执行Base再执行Derived。

2、b->Func();

此句的执行结果为:

Derived::Func()

Derived::virtual_Test()

Derived::non_virtual_Test()

首先,先让大家知道什么是静态绑定,什么是动态绑定。很简单,举个例子说明。

D *pD = new D(); 静态类型是*D,动态类型是*D

B *pB = pD; 静态类型是*B,即定义的类型;动态类型为*D,即所指向的类型

所谓静态绑定就是在编译期就确定的类型,如上所说的静态类型;动态绑定就是在运行期才确定的类型,如上所说的动态类型。

看b->Func();因为Func()是virtual函数,所以对象调用的是动态类型,也就Derived::Func(),Func()函数里面又调用了两个函数virtual_Test()和non_virtual_Test(),一样遵循上面的规制,virtual_Test()调用的是动态类型的Derived::virtual_Test(),而non_virtual_Test()调用的是Derived::Func()所属对象的Derived::non_virtual_Test()。

3、b->Func1();

此句的执行结果为:

Base::Func1()

Derived::virtual_Test()

Base::non_virtual_Test()

对于Func1()的执行也类似,Func1()是non-virtual函数,所以调用对象调用的是静态类型的Base::Func1(),然后virtual_Test()调用的是动态类型的Derived:: virtual_Test(),而non_virtual_Test()调用的是Base::Func1()所属对象的Base::non_virtual_Test()。

不近视的程序YUAN可能会发现Base构造函数中调用了virtual函数,按上面的规则,调用的应该是Derived::init()才对,是事实却是调用了Base::init()。这里要说明的就是这是特殊的情况,在构造函数中是没有多态的,这也符合常理,因为构造函数就是确定一个对象的内容的时候,那么对象都还确定,所以也就实现不了多态。

4、delete b;

此句的执行结果为:

Base::Delete()

按照对象销毁的顺序,是跟构造的顺序相反的,也就是先销毁派生类的再销毁基类的,但这里没有调用~D()这个函数,等一下再说明原因。调用了~B()函数,~B()函数中调用了Delete()函数,它是一个virtual函数,遵循上面说到的规则,是执行~B()所属对象的Base::Delete()。为什么会没有执行到Derived的析构函数呢,我们看下面这则规则:C++明白指出,当derived class 对象经由一个base class指针被删除,而该base class带着一个non-virtual析构函数,其结果未有定义——实际执行时通常发生的是对象的derived成分没有被销毁。因为析构函数不是virtual的,所以并没有执行derived的析构函数,由此引申出:如果基类有virtual成员函数,就应该声明一个virtual的析构函数。这是好的编程习惯,有利于减少内存泄露。还有就是不要改变继承而来的non-virtual函数,这是不好的编程风格。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: