当前位置:编程学习 > C/C++ >>

【Deep C (and C++)】深入理解C/C++(4)

译自Deep C (and C++) by Olve Maudal and Jon Jagger,本身半桶水不到,如果哪位网友发现有错,留言指出吧:)

 

总结一下第三讲,我们可以知道,相对于第一位候选者,第二位候选者在以下几个方面有更深的认识:

1、  C与C++的联系;

2、  多态方面的技术;

3、  如何正确的初始化一个对象;

4、  Rule of three;

5、  操作符new[]与操作符delete[]方面的知识;

6、  常用的命名约定。

 

接下来,我们将分享一下几个方面的知识:

1、  对象的生命周期;

2、  Rule of three;

3、  虚函数表。

 

先来看,恰当地进行对象初始化。赋值与初始化是不一样的。来看这段代码的输出:


struct A 

    A() { puts("A()"); } 
    A(int v) { puts("A(int)"); } 
    ~A() { puts("~A()"); } 
}; 
 
struct X 

    X(int v) { a = v; } 
    X(long v):a(v) { } 
    A a; 
}; 
 
int main() 

    puts("bad style"); 
    { 
       X slow(int(2)); 
    } 
    puts("good style"); 
    { 
       X fast(long(2)); 
    } 

代码输出为:


bad style 
A() 
A(int) 
~A() 
~A() 
good style 
A(int) 
~A() 
再看看对象的生命周期:

C++的一个基本原理是:对象消亡时候需要采取的操作,正好是对象创建时候所采取操作的逆操作。

看下面的代码:


struct A 

    A() { puts("A()"); } 
    ~A() { puts("~A()"); } 
}; 
 
struct B 

    B() { puts("B()"); } 
    ~B() { puts("~B()"); } 
}; 
 
struct C 

    A a; 
    B b; 
}; 
 
int main() 

    C obj; 

程序的输出是:


A() 
B() 
~B() 
~A() 
再看:


struct A 

    A():id(count++) 
    { 
       printf("A(%d)\n", id); 
    } 
    ~A() 
    { 
       printf("~A(%d)\n", id); 
    } 
    int id; 
    static int count; 
}; 
 
//原文是没有这句的,不过根据C++规范,static数据成员必须在类定义体外定义。 
//谢谢yuxq100指出。 
int A::count = 0; 
 
int main() 

    A array[4]; 

程序输出:

 


A(0) 
A(1) 
A(2) 
A(3) 
~A(3) 
~A(2) 
~A(1) 
~A(0) 
仔细看着张图,也会有所收获:

 

接下来看看:the rule of three:

If a class defines a copy constructor, acopy assignment operator, or a destructor, then it should define all three.

如果一个类定义了拷贝构造函数、赋值操作符、析构函数中的一个,那么通常需要全部定义这仨函数。

如图示:


接下类看看虚函数表:

看一下这段代码,虚函数表的结构大概如何呢?


struct base 

    virtual void f(); 
    virtual void g(); 
    int a,b; 
}; 
 
struct derived:base 

    virtual void g(); 
    virtual void h(); 
    int c; 
}; 
 
void poly(base* ptr) 

    ptr->f(); 
    ptr->g(); 

 
int main() 

    poly(&base()); 
    poly(&derived()); 

虚函数表结构如何呢?看图:


简单说明:派生类没有重载f函数,它继承了基类的f函数,因此,派生类的虚函数表的f函数指向基类的f函数。但是,因为派生类重载了g函数,因此,其虚函数表中的g指向自身的g函数。

 

那么这段代码呢?


struct base 

    void f(); 
    virtual void g(); 
    int a,b; 
}; 
 
struct derived:base 

    virtual void g(); 
    virtual void h(); 
    int c; 
}; 
 
void poly(base* ptr) 

    ptr->f(); 
    ptr->g(); 

 
int main() 

    poly(&base()); 
    poly(&derived()); 

基类的f函数不是虚函数了,这个时候的虚函数表结构又如何呢?


越多的同事对他们所使用的语言有深入的认识,这对你有什么好处吗?我们不建议(也不实际)要求公司里所有的C/C++程序员都深入理解C/C++。但是你确实需要绝大部分的程序员真的在意他们的专业度,他们需要求知若渴,不断努力,争取不断的加深对语言本身的理解。正所谓:stay hungry,stay foolish:)

 

现在回过头了看着这两名开发者,也就是我们之前所一直说的候选者。

亲,你觉得这两名开发者之间最大的差别在哪?

关于语言的现有知识吗?   不是!!

是他们对于学习的态度!!

 

你最后一次上编程方面的课程是什么时候?

第一个候选者这样回答:你什么意思?我在大学里学习编程,现在我通过实践来学习。你想知道什么?

你:那么,你现在在阅读哪些书?

候选者:书?哦,我不需要书。在我需要的时候,我会在网上查询手册。

你:你会跟你的同事谈论编程方面的东西吗?

候选者:我觉得没有必要!!我比他们强多了,从他们身上学不到任何玩意!!

 

你貌似对C/C++了解的更多,怎么做到的?

第二个候选者:我每天都会学习一些新东西,我真的乐在其中:)

我偶尔也会在stackoverflow.com、comp.lang.c还有comp.lang.c++跟进一些讨论。

我还参加了一个当地的C/C++用户组,我们定期会举行一些讨论会,交流心得。

我看了很多的书,很多很多。你知道吗?James Grenning刚刚写了一本很不错的书:《Test-Driven Development in C》,很值得一看:)

[PS:貌似是:Test-DrivenDevelopment for Embedded C]

我偶尔会被允许拜访WG14W以及G21。

[PS:
ISO WG14:ISO C委员会,具体指JTC1/SC22/WG14 C语言技术工作小组,通常简写为WG14。    ISO WG21:ISO C++委员会,具体指JTC1/SC22/WG21 C++技术工作小组,通常简写成WG21。
此人很牛逼呀:)]

我还是ACCU的会员,这里的人对于编程都有专业精神。我订阅了Overload,CVu及accu的一些综述文章。

[PS:移步看看ACCU的网站,确实应该去看看:

ACCU is an organisation of programmers whocare about professionalism in programming and are dedicated to raising th

补充:软件开发 , C++ ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,