10道C++输出易错笔试题收集_3

#include


using namespace std;

class A

{

int x;

public:

A() { cout << "A's constructor called " << endl; }

};

class B

{

static A a;

public:

B() { cout << "B's constructor called " << endl; }

static A getA() { return a; }

};

A B::a; // definition of a

int main()

{

B b1, b2, b3;

A a = b1.getA();

return 0;

}

背景:

阅读新闻

Java编程思想重点笔记(Java开发必看)

[日期:2015-01-09]

来源:Linux社区

作者:lanxuezaipiao

[字体:大 中 小]

Java编程思想,Java学习必读经典,不管是初学者还是大牛都值得一读,这里总结书中的重点知识,这些知识不仅经常出现在各大知名公司的笔试面试过程中,而且在大型项目开发中也是常用的知识,既有简单的概念理解题(比如is-a关系和has-a关系的区别),也有深入的涉及RTTI和JVM底层反编译知识。

1. Java中的多态性理解(注意与C++区分)

Java中除了static方法和final方法(private方法本质上属于final方法,因为不能被子类访问)之外,其它所有的方法都是动态绑定,这意味着通常情况下,我们不必判定是否应该进行动态绑定—它会自动发生。

final方法会使编译器生成更有效的代码,这也是为什么说声明为final方法能在一定程度上提高性能(效果不明显)。

如果某个方法是静态的,它的行为就不具有多态性:

class StaticSuper {

public static String staticGet() {

return "Base static九度快排系统 https://www.190seo.comGet()";

}

public String dynamicGet() {

return "Base dynamicGet()";

}

}

class StaticSub extends StaticSuper {

public static String staticGet() {

return "Derived staticGet()";

}

public String dynamicGet() {

return "Derived dynamicGet()";

}

}

public class StaticPolymorphism {

public static void main(String[] args) {

StaticSuper sup = new StaticSub();

System.out.println(sup.staticGet());

System.out.println(sup.dynamicGet());

}

}

输出:

Base staticGet()

Derived dynamicGet()

构造函数并不具有多态性,它们实际上是static方法,只不过该static声明是隐式的。因此,构造函数不能够被override。

在父类构造函数内部调用具有多态行为的函数将导致无法预测的结果,因为此时子类对象还没初始化,此时调用子类方法不会得到我们想要的结果。

class Glyph {

void draw() {

System.out.println("Glyph.draw()");

}

Glyph() {

System.out.println("Glyph() before draw()");

draw();

System.out.println("Glyph() after draw()");

}

}

class RoundGlyph extends Glyph {

private int radius = 1;

RoundGlyph(int r) {

radius = r;

System.out.println("RoundGlyph.RoundGlyph(). radius=" + radius);

}

void draw() {

System.out.println("RoundGlyph.draw(). radius=" + radius);

}

}

public class PolyConstructors {

public static void main(String[] args) {

new RoundGlyph(5);

}

}

输出:

Glyph() before draw()

RoundGlyph.draw(). radius=0

Glyph() after draw()

RoundGlyph.RoundGlyph(). radius=5

为什么会这样输出?这就要明确掌握Java中构造函数的调用顺序:

(1)在其他任何事物发生之前,将分配给对象的存储空间初始化成二进制0;

(2)调用基类构造函数。从根开始递归下去,因为多态性此时调用子类覆盖后的draw()方法(要在调用RoundGlyph构造函数之前调用),由于步骤1的缘故,我们此时会发现radius的值为0;

(3)按声明顺序调用成员的初始化方法;

(4)最后调用子类的构造函数。

只有非private方法才可以被覆盖,但是还需要密切注意覆盖private方法的现象,这时虽然编译器不会报错,但是也不会按照我们所期望的来执行,即覆盖private方法对子类来说是一个新的方法而非重载方法。因此,在子类中,新方法名最好不要与基类的private方法采取同一名字(虽然没关系,但容易误解,以为能够覆盖基类的private方法)。

Java类中属性域的访问操作都由编译器解析,因此不是多态的。父类和子类的同名属性都会分配不同的存储空间,如下:

// Direct field access is determined at compile time.

class Super {

public int field = 0;

public int getField() {

return field;

}

}

class Sub extends Super {

public int field = 1;

public int getField() {

return field;

}

public int getSuperField() {

return super.field;

}

}

public class FieldAccess {

public static void main(String[] args) {

Super sup = new Sub();

System.out.println("sup.filed=" + sup.field +

", sup.getField()=" + sup.getField());

Sub sub = new Sub();

System.out.println("sub.filed=" + sub.field +

", sub.getField()=" + sub.getField() +

", sub.getSuperField()=" + sub.getSuperField());

}

}

输出:

sup.filed=0, sup.getField()=1

sub.filed=1, sub.getField()=1, sub.getSuperField()=0

Sub子类实际上包含了两个称为field的域,然而在引用Sub中的field时所产生的默认域并非Super版本的field域,因此为了得到Super.field,必须显式地指明super.field。

2. is-a关系和is-like-a关系

is-a关系属于纯继承,即只有在基类中已经建立的方法才可以在子类中被覆盖,如下图所示:

基类和子类有着完全相同的接口,这样向上转型时永远不需要知道正在处理的对象的确切类型,这通过多态来实现。

is-like-a关系:子类扩展了基类接口。它有着相同的基本接口,但是他还具有由额外方法实现的其他特性。

缺点就是子类中接口的扩展部分不能被基类访问,因此一旦向上转型,就不能调用那些新方法。

3. 运行时类型信息(RTTI + 反射)

概念

RTTI:运行时类型信息使得你可以在程序运行时发现和使用类型信息。

使用方式

Java是如何让我们在运行时识别对象和类的信息的,主要有两种方式(还有辅助的第三种方式,见下描述):

一种是“传统的”RTTI,它假定我们在编译时已经知道了所有的类型,比如

另一种是“反射”机制,它运行我们在运行时发现和使用类的信息,即使用。

其实还有第三种形式,就是关键字,它返回一个bool值,它保持了类型的概念,它指的是“你是这个类吗?或者你是这个类的派生类吗?”。而如果用==或equals比较实际的Class对象,就没有考虑继承—它或者是这个确切的类型,或者不是。

工作原理

要理解RTTI在Java中的工作原理,首先必须知道类型信息在运行时是如何表示的,这项工作是由称为的特殊对象完成的,它包含了与类有关的信息。Java送Class对象来执行其RTTI,使用类加载器的子系统实现。

无论何时,只要你想在运行时使用类型信息,就必须首先获得对恰当的Class对象的引用,获取方式有三种:

(1)如果你没有持有该类型的对象,则就是实现此功能的便捷途,因为它不需要对象信息;

(2)如果你已经拥有了一个感兴趣的类型的对象,那就可以通过调用方法来获取Class引用了,它将返回表示该对象的实际类型的Class引用。Class包含很有有用的方法,比如:

package rtti;

interface HasBatteries{}

interface WaterProof{}

interface Shoots{}

class Toy {

Toy() {}

Toy(int i) {}

}

class FancyToy extends Toy

implements HasBatteries, WaterProof, Shoots {

FancyToy() {

super(1);

}

}

public class RTTITest {

static void printInfo(Class cc) {

System.out.println("Class name: " + cc.getName() +

", is interface? [" + cc.isInterface() + "]");

System.out.println("Simple name: " + cc.getSimpleName());

System.out.println("Canonical name: " + cc.getCanonicalName());

}

public static void main(String[] args) {

Class c = null;

try {

c = Class.forName("rtti.FancyToy"); // 必须是全限定名(包名+类名)

} catch(ClassNotFoundException e) {

System.out.println("Can't find FancyToy");

System.exit(1);

}

printInfo(c);

for(Class face : c.getInterfaces()) {

printInfo(face);

}

Class up = c.getSuperclass();

Object obj = null;

try {

// Requires default constructor.

obj = up.newInstance();

} catch (InstantiationException e) {

System.out.println("Can't Instantiate");

System.exit(1);

} catch (IllegalAccessException e) {

System.out.println("Can't access");

System.exit(1);

}

printInfo(obj.getClass());

}

}

输出:

Class name: rtti.FancyToy, is interface? [false]

Simple name: FancyToy

Canonical name: rtti.FancyToy

Class name: rtti.HasBatteries, is interface? [true]

Simple name: HasBatteries

Canonical name: rtti.HasBatteries

Class name: rtti.WaterProof, is interface? [true]

Simple name: WaterProof

Canonical name: rtti.WaterProof

Class name: rtti.Shoots, is interface? [true]

Simple name: Shoots

Canonical name: rtti.Shoots

Class name: rtti.Toy, is interface? [false]

Simple name: Toy

Canonical name: rtti.Toy

(3)Java还提供了另一种方法来生成对Class对象的引用,即使用类字面常量。比如上面的就像这样:来引用。

这样做不仅更简单,而且更安全,因为它在编译时就会受到检查(因此不需要置于try语句块中),并且它根除了对forName方法的引用,所以也更高效。类字面常量不仅可以应用于普通的类,也可以应用于接口、数组以及基本数据类型。

注意:当使用“.class”来创建对Class对象的引用时,不会自动地初始化该Class对象,初始化被延迟到了对静态方法(构造器隐式的是静态的)或者非final静态域(注意final静态域不会触发初始化操作)进行首次引用时才执行:。而使用Class.forName时会自动的初始化。

为了使用类而做的准备工作实际包含三个步骤:

- 加载:由类加载器执行。查找字节码,并从这些字节码中创建一个Class对象

- 链接:验证类中的字节码,为静态域分配存储空间,并且如果必需的话,将解析这个类创建的对其他类的所有引用。

- 初始化:如果该类具有超类,则对其初始化,执行静态初始化器和静态初始化块。

这一点非常重要,下面通过一个实例来说明这两者的区别:

package rtti;

import java.util.Random;

class Initable {

static final int staticFinal = 47;

static final int staticFinal2 = ClassInitialization.rand.nextInt(1000);

static {

System.out.println("Initializing Initable");

}

}

class Initable2 {

static int staticNonFinal = 147;

static {

System.out.println("Initializing Initable2");

}

}

class Initable3 {

static int staticNonFinal = 74;

static {

System.out.println("Initializing Initable3");

}

}

public class ClassInitialization {

public static Random rand = new Random(47);

public static void main(String[] args) {

// Does not trigger initialization

Class initable = Initable.class;

System.out.println("After creating Initable ref");

// Does not trigger initialization

System.out.println(Initable.staticFinal);

// Does trigger initialization(rand() is static method)

System.out.println(Initable.staticFinal2);

// Does trigger initialization(not final)

System.out.println(Initable2.staticNonFinal);

try {

Class initable3 = Class.forName("rtti.Initable3");

} catch (ClassNotFoundException e) {

System.out.println("Can't find Initable3");

System.exit(1);

}

System.out.println("After creating Initable3 ref");

System.out.println(Initable3.staticNonFinal);

}

}

输出:

After creating Initable ref

47

Initializing Initable

258

Initializing Initable2

147

Initializing Initable3

After creating Initable3 ref

74

RTTI的限制?如何突破? — 反射机制

如果不知道某个对象的确切类型,RTTI可以告诉你,但是有一个限制:这个类型在编译时必须已知,这样才能使用RTTI识别它,也就是在编译时,编译器必须知道所有要通过RTTI来处理的类。

可以突破这个限制吗?是的,突破它的就是反射机制。

类与类库一起对反射的概念进行了支持,该类库包含了、以及类(每个类都实现了接口)。这些类型的对象是由JVM在运行时创建的,用以表示未知类里对应的成员。这样你就可以使用创建新的对象,用方法读取和修改与对象关联的字段,用方法调用与对象关联的方法。另外,还可以调用等很便利的方法,以返回表示字段、方法以及构造器的对象的数组。这样,匿名对象的类信息就能在运行时被完全确定下来,而在编译时不需要知道任何事情。

更多详情见请继续阅读下一页的精彩内容: http://www.linuxidc.com/Linux/2015-01/111506p2.htm

linux

12下一页

10道C++输出易错笔试题收集

优酷土豆2014校园招聘笔试题目之Java开发类

相关资讯

Java编程

Java 老矣,尚能饭否? (今 19:38)

Java 并发编程中使用 ReentrantLoc (12/05/2015 22:49:19)

for(int a:i)在Java 编程中的使用 (08/24/2015 07:29:34)

Java编程基本概念 (03月07日)

10个实用的但偏执的Java编程技术 (08/31/2015 17:39:22)

Java:过去、未来的互联网编程之王 (07/31/2015 14:50:02)

本文评论

查看全部评论 (1)

表情: 表情

姓名:

匿名

字数

同意评论声明

评论声明

尊重网上道德,遵守中华人民共和国的各项有关法律法规

承担一切因您的行为而直接或间接导致的民事或刑事法律责任

本站管理人员有权保留或删除其管辖留言中的任意内容

本站有权在网站内转载或引用您的评论

参与本评论即表明您已经阅读并接受上述条款

第 1 楼* pcfine会员 发表于 2015/1/12 13:10:44mark回复 支持 (0) 反对 (0)

最新资讯

Java 老矣,尚能饭否?

Google 再次从官方商店下架伪装成合法程序

一铭桌面操作系统4.0 SP1安装使用初体验

Opus 1.2发布,开源免专利费音频编解码器

Java中抽象类的定义和使用

Java实现内部类

C语言如何分离一个数的高低位,如何将两个

C语言之鞍点的查找

C语言实现牛顿迭代法解方程

Android编译系统产品线(基于友善之臂

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,711评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,932评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,770评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,799评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,697评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,069评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,535评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,200评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,353评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,290评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,331评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,020评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,610评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,694评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,927评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,330评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,904评论 2 341

推荐阅读更多精彩内容