re: 几道笔试题 Noock 2010-07-21 23:54
关于第3道,还有一种继承方式,就是virtual继承,在多继承的时候会用到
当然virtual与public、protected、private不是一类,它们是可以叠加的
re: C++的流设计很糟糕 Noock 2010-07-09 20:41
@那谁
不光是对于char型的不行,对于int、short使用%u输出也不行,这是printf最致命的问题。
你可以不承认LOG宏是解决了你的问题,但它是一个可以获得期望行为的,保证输出的正确性,而使用printf会导致程序错误的输出。
如果你非得要使用printf,给个建议,在自定义的函数内检查格式字符串,当发现有%u时,可以检测它的值是正的还是负的,如果是负的可以给个警告或者抛出异常,保证行为的正确性。
不要在“规避”还是“解决”两个词之间找别扭了,保证程序的正确性才是根本。
printf会给你提供更多的出错机会
还要程序员时刻得着各个转义字符的对应关系,我是比较懒,我是记不住
而且__attribute__也只有GCC在新版本中扩展功能才有,其它编译器是不支持的
使用printf还会影响到使用std::string,这两个混着用还经常会忘了调用.c_str()方法,这样在有些编译器是安全的,但很多编译器也会产生致命的错误
使用printf如果参数比较多的话还容易造成顺序错误
re: C++的流设计很糟糕 Noock 2010-07-09 15:14
@那谁
1) gcc标准库的printf也是加了__attribute__选项的,也能解决大部分的格式符,但上面我的那个例子是不行的,
你可以试一下你自己写的函数
你也可以把你的函数帖出来,我帮你验证一下。
2)既然你使用自己封装的函数来打印,跟我原来定义一个宏LOG( )当函数用来比有什么优势。
re: C++的流设计很糟糕 Noock 2010-07-09 13:38
@那谁
软件最基本要求是正确,请教如果使用printf下面这个问题如何解决?
char cc = -1;
printf("cc=%u\n", cc);
gcc 4.3.4 :
cc=4294967295
g++ -Wall 没有任何警告
re: C++的流设计很糟糕 Noock 2010-07-09 09:27
@那谁
别老想着让编译器解决,C++设计语言的指导思想之一就是能通过已有特性解决的问题就不进行语言特性扩展,别一门心思地让编译器来解决
编译器这么多,只要不列入C++标准,所有的扩展都是不可移植的
考虑问题是不是可以换个角度呢?
re: C++的流设计很糟糕 Noock 2010-07-08 23:47
@那谁
至少现在C++通过自己的特性还是解决了你的问题,运算符只是个函数而已,如何去使用是程序员自己的事,C++委员会也不会接受为了一个函数调用去修改C++的特性的。这个与C++的流设计也没有什么关系,你上来就一个大标题,
“C++的流设计很糟糕”
是不是有点儿太不负责任了?
re: C++的流设计很糟糕 Noock 2010-07-08 23:41
@那谁
编译器扩展是牺牲了可移植性的,当然你也可以通过写个宏去避免这个问题
#define LOG( content ) lstream<<content<<LoggerStream::end
LOG( "str1"<<1<<"str"<<2);
这个能不能满足你的要求呢?
re: C++的流设计很糟糕 Noock 2010-07-08 23:25
@那谁
另外,还有个问题,很难在编译语法层面保证你的最后一个输入是那个标记类吧....
这个你使用printf更容易出问题,后面几个参数在编译时是检测不出来的,运行时会致命的。
而且使用printf %d 输出long long都有可能致命
而且,你定义的变量日后修改类弄,你容易没的修改格式字符串,那样你的程序会在不必要的写日志时崩溃,而且是不确定的崩溃,在不确定平台崩溃,有的平台会死,有些平台却没事儿
re: C++的流设计很糟糕 Noock 2010-07-08 23:17
不解决你说的问题吗?
re: C++的流设计很糟糕 Noock 2010-07-08 23:09
#include <iostream>
#include <ostream>
#include <sstream>
#include <strstream>
using namespace std;
struct streamend { };
class LoggerStream : public stringstream //public std::ostrstream
{
public:
static streamend end;
~LoggerStream( ) { DoPrint(); }
private:
void DoPrint( void )
{
cout<<"------- DoPrint( ) ------------"<<endl; // 只是用来证明何时调用了这个东东
cout<<this->str(); // real string
this->str("");
}
private:
friend ostream& operator<<(ostream& os, const streamend& end);
};
streamend LoggerStream::end;
// 第二个参数只是用来支持结束符
ostream& operator<<(ostream& os, const streamend&)
{
#if 1 // 0或1两种方法都可以
ostream* pos = &os;
LoggerStream* pls = dynamic_cast<LoggerStream*>(pos);
if( pls != NULL)
pls->DoPrint();
#else
if( typeid(os) == typeid(LoggerStream))
((LoggerStream*)(&os))->DoPrint();
#endif
return os;
}
int main()
{
LoggerStream lstream; // 你只需要构造一次,也可以声明为静态的
lstream << 1 << " hello world\n"<<LoggerStream::end;
lstream <<"line 1"<<LoggerStream::end<<"\nline 2\n"<<LoggerStream::end;
stringstream ss;
ss<<"hello"<<LoggerStream::end; // 此处LoggerStream::end没有任何影响
return 0;
}
re: C++的流设计很糟糕 Noock 2010-07-08 13:06
C++语言本身没有任何问题,是你掌握得不是很熟练。
C++作为语言,只是一种表达工具,而一个设计的好坏跟语言本身是没有任何关系的,只要有思想,C++可以做出非常好的设计的。
之所以以怀疑流的使用,只是你还没有理解流,还没有了解如何学得更好。
别动不动就批C++,还没有理解它怎么能知道它不好呢?
C++难是难,学起来非常困难,难是因为它太强大,造自行车不难,学会骑自行车也不难,而造飞机与开飞机就非常难,没开好飞机摔了,能说飞机不好吗?