游戏开发论坛

 找回密码
 立即注册
搜索
查看: 10793|回复: 23

小谈目前C++编译器一些不太合理的地方。

[复制链接]

59

主题

1104

帖子

1199

积分

金牌会员

Rank: 6Rank: 6

积分
1199
发表于 2004-6-5 12:43:00 | 显示全部楼层 |阅读模式
我那篇帖子中的关于模版类的链接问题是一个。
另外关于虚函数的隐藏的问题,也是一个比较奇怪的地方。
见下面这个例子:
class A
{
public:
    virtual int foo() = 0;
};

class B : public A
{
public:
    virtual int foo() {return 10;}
};

#include <iostream.h>
int main()
{
    B b;
    B *pointer_b = &b;
    A *pointer_a = &b;
    cout << pointer_b->foo() << endl;
    cout << pointer_a->foo() << endl;
    return 0;
}
==========================
这是个很简单的例子,因为重载了,所以输出的是两个10。
但是如果我把class A这个基类改成:
class A
{
public:
    int foo() { return 20 };
};
那么结果就会是10和20,如果我把class A再改成:
class A
{
public:
    virtual int foo() { return 20 };
};
那么结果还是两个10,这个叫覆盖。
===================================
这个现象是可以解释的,因为虚函数在类里面有一个vft表,当找不到实函数的时候,就会去虚函数里面找,但是实函数优先。所以第二个例子,也就是隐藏的时候,会直接呼叫基类的foo,即使pointer_a和pointer_b这两个指针完全一模一样。

这样导致的问题就是很多人在设计C++程序的时候,基类被无意中修改过,编译不会报错,但是运行的时候却发现很诡异的错误,同样的指针,呼叫同样的函数,传同样的参数,出来的结果却不一样。失败。。-。-

******************************************************
另外一个俺发现的C++不太爽的地方就是跟我开始讲的那个template的问题有关系的。
要知道,所有写在类里面的函数,都会被定义为inline,而因为开始我讲的那个原因,所有的STL都是直接在头文件里面写代码的,这样一来,用了STL的程序,因为inline的原因会变得奇大无比,而且这个问题暂时没法解决。也就是说,在类定义的时候定义的函数,没法不让它inline。。。。日。

0

主题

130

帖子

130

积分

注册会员

Rank: 2

积分
130
发表于 2004-6-5 14:26:00 | 显示全部楼层

Re:小谈目前C++编译器一些不太合理的地方。

这是C++的基本特征:多态啊.
建议你看看OO,和DESIGN PATTERN的书.

59

主题

1104

帖子

1199

积分

金牌会员

Rank: 6Rank: 6

积分
1199
 楼主| 发表于 2004-6-5 14:46:00 | 显示全部楼层

Re:小谈目前C++编译器一些不太合理的地方。

多态是多态,带了个名字就不代表是先进的。
你说说这个的好处?

我想大家在设计程序的时候大概都是设计一个基类。
然后在基类上派生出子类。
然后传递参数的时候,都是用基类传递,然后调用成员函数的时候都是想调用子类的成员函数吧?比如你定义一个基类:
人类,从中派生出男人和女人
人类这个基类中有个叫呼吸的函数,设计的时候为了防止以后派生出一个死人
就写了一个默认的呼吸方式。
但是男人和女人都有自己的呼吸方式,在传递参数的时候,你把男人或者女人
强行cast成了人类传递过去,当再调用呼吸函数的时候,就成了人类这个基类的默认呼吸函数了。

当然,这个设计有些不合理的地方,应该把呼吸置为纯虚函数。
那么多态性究竟在编程中是好的还是坏的呢?

90

主题

797

帖子

833

积分

高级会员

论坛版主

Rank: 4

积分
833
QQ
发表于 2004-6-5 15:25:00 | 显示全部楼层

Re:小谈目前C++编译器一些不太合理的地方。

哈哈。比喻的有些意思

2

主题

20

帖子

28

积分

注册会员

Rank: 2

积分
28
发表于 2004-6-6 13:44:00 | 显示全部楼层

Re:小谈目前C++编译器一些不太合理的地方。

多态作为OO的一个基本特征,其好处是无须置疑的.
楼主谈到的问题其实并不是C++的错,是程序员自己的问题.不过编译器能警告也就好了(C++的警告超多 大型程序估计也就被淹没在警告的海洋中了)

第二个inline的问题楼主显然没有搞清楚 inline 的意思.C++标准规定,inline只是表示程序员希望该函数可以在编译时被决议为 inline 但是是否在编译时成为inline函数,还是要视编译时的效果而定.如果一个大函数被频繁调用引起代码过长的话,c++是不会把他编译为inline的.(我个人最喜欢使用STL般的使用库的方法了,所有的代码都可以看到,只要include一下就可以了~)

59

主题

1104

帖子

1199

积分

金牌会员

Rank: 6Rank: 6

积分
1199
 楼主| 发表于 2004-6-6 14:31:00 | 显示全部楼层

Re:小谈目前C++编译器一些不太合理的地方。

多态好象不只是仅仅简单的指这个吧,除了我说的这个,多态还包括很多呢。
我说的这个有啥好处?偶到是没觉得。

写在类定义里面的函数,都会被默认的申请inline,至于是否真的inline,那是后话,但是我说的问题是,自从template必须写在类里面的情况下,所有你想定义的template的地方,都会被默认的申请inline,有些时候你并不想它inline的,比如说在设计某些基类的时候,该基类会被大量的使用,从而导致编译出来的东西奇大无比。

就好象STL一样,很多情况下,我就想调用STL像呼叫一个函数一样,而不想想操作一个宏一样,但是很多时候你无法控制这个,因为你根本不知道他是否inline了。而平常写的函数,在没申请inline的情况下,是肯定不会inline的,在必须要inline的情况下,你可以强制inline,那么对于这种默认就是申请inline的东西,对于一个开发者来说,对自己的代码基本上不知道究竟要怎么做。

36

主题

1047

帖子

1147

积分

金牌会员

Rank: 6Rank: 6

积分
1147
发表于 2004-6-7 09:13:00 | 显示全部楼层

Re:小谈目前C++编译器一些不太合理的地方。

看得我是苦笑不得...
总的看来,你对 c++ 的了解还停留在表面上,不过也没什么,我以前也是由过这些疑问,第二,你对 template 的了解几乎没有,template != 宏定义,在你所写的 template 代码中并不是所有的代码都要编译连接到最终代码里的,而是根据调用代码来决定的。这些都是由编译器来决定的,我们要相信编译器的这些开发高手们,我们想到得问题他们早已经想过了,我们没想到的,人家也都想到了。有一本介绍 template 的书很不错,《 c++ template 》 有中文版,不妨拿来看看。
另外,火气不要太大,大家讨论问题,其他得东西对我们没有任何帮助。

59

主题

1104

帖子

1199

积分

金牌会员

Rank: 6Rank: 6

积分
1199
 楼主| 发表于 2004-6-7 11:19:00 | 显示全部楼层

Re:小谈目前C++编译器一些不太合理的地方。

楼上的,别动不动说一些听起来吓得死人的结论。
你把我写的东西看明白再说,OK?别看到一个“宏”字就像发现新大陆一样,看明白再说话,要不俺会对你伸中指,鄙视的说。
我说template的东西之所以要写在template class的定义里面,默认的就申请了inline。就好象:
class A {
public:
    A() {}
}
一样,这个时候,A的构造函数是自动申请inline了的,你没法取消这个inline,对于一般类的话,你可以用
class A {
public:
    A();
}
A::A()
{
}
来取消掉这个自动申请的inline,还可以使用:
inline A::A()
{
}
来使它申请inline。
但是于STL来说,所有的STL都写在类的定义里面,你根本无法知道究竟是否是inline了,因为有一些情况下,也许你根本不希望inline。STL为什么要这么写呢?因为template根本就不支持在link的时候去找到自己的函数的定义。因为template类会在使用到template类的时候,根据不同的类型去找不同的定义。比如:
template<class T> class A {
public:
    A() {}
};
当你用到A<int> test;的时候,编译器去找的是一个叫hello<int>的定义,因为找不到,所以无法编译。其实要增加这个功能也很简单,只不过在编译obj的时候,对于模版类要特殊处理,输出特殊标记的函数名,然后链接的时候去寻找这个特殊标记的函数名即可。现在这个东西渐渐的在各大C++编译器的论坛都有讨论,估计以后逐渐都会开始支持的。

36

主题

1047

帖子

1147

积分

金牌会员

Rank: 6Rank: 6

积分
1147
发表于 2004-6-7 14:43:00 | 显示全部楼层

Re:小谈目前C++编译器一些不太合理的地方。

嗯,写得很详细,不过既然你认为很简单就能实现,不如吧这个建议给 ms 送去,没准可以采纳。
但是我很不理解,这么简单的事情为什么现在主流的 c++ 编译器都不支持呢?:)

59

主题

1104

帖子

1199

积分

金牌会员

Rank: 6Rank: 6

积分
1199
 楼主| 发表于 2004-6-7 15:34:00 | 显示全部楼层

Re:小谈目前C++编译器一些不太合理的地方。

.....给MS发了封EMAIL,回的解决方案是:
要么就都写在头文件里面。
要么就是你十分清楚你的template将要如何使用,然后在mytemplate.cpp的实现里面写:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-7-1 15:57

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表