| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 3897 人关注过本帖, 2 人收藏
标题:C++ FAQ from CSDN
只看楼主 加入收藏
yuyunliuhen
Rank: 6Rank: 6
等 级:贵宾
威 望:20
帖 子:1435
专家分:0
注 册:2005-12-12
收藏
得分:0 

在C和C++中把标准输出重定向到指定文件
C++的实现
fstream fs("c:\\a.txt", ios::out);
streambuf* pOld = cout.rdbuf(fs.rdbuf());
cout<< "my lover!"<<endl; //这句将输出到c:\a.txt上去
cout.rdbuf(pOld);
cout<< "come on"<<endl; //这句将输出到控制台。

C的实现
#include <ios>
#include <iostream>
#include <fstream>
//若使用包含.h文件方式则编译报错

using namespace std;

void main()
{
ofstream ofs("e:\\a.txt");
streambuf *osb = cout.rdbuf(ofs.rdbuf());
cout << "to file" << endl;
cout.rdbuf(osb);
cout << "to term" << endl;
}

啊,这样对于实现来说可能不是很妥,改成手动刷新缓冲才有应用价值
#include <stdio.h>
#include <string.h>

void main()
{
FILE old_stdout;
FILE *fp = fopen("e:\\a.txt", "w");

memcpy(&old_stdout, &_iob[1], sizeof(FILE));
memcpy(&_iob[1], fp, sizeof(FILE));

/*call any functions..*/
printf("to file");
/**/

/*把缓冲刷新到文件*/
fflush(stdout);
memcpy(&_iob[1], &old_stdout, sizeof(FILE));
printf("to term");
fclose(fp);
}



Go confidently in the  directions of your dreams,live the life you have imagined!Just do it!
It is no use learning without thinking!
2007-03-13 16:35
litcatyx
Rank: 1
等 级:新手上路
威 望:1
帖 子:151
专家分:0
注 册:2006-10-27
收藏
得分:0 
不错,学到不少东西,谢谢楼主

2007-03-13 21:42
song4
Rank: 7Rank: 7Rank: 7
等 级:贵宾
威 望:38
帖 子:1533
专家分:4
注 册:2006-3-25
收藏
得分:0 
怎么不加精
趁有时间,多要点精华

嵌入式 ARM 单片机 驱动 RT操作系统 J2ME LINUX  Symbian C C++ 数据结构 JAVA Oracle 设计模式 软件工程 JSP
2007-03-13 22:39
yuyunliuhen
Rank: 6Rank: 6
等 级:贵宾
威 望:20
帖 子:1435
专家分:0
注 册:2005-12-12
收藏
得分:0 

自己给自己加不大好吧..呵呵
song4你也学JAVA了,我也是才开始,C++你学的真不错,以后还请多多指教

Go confidently in the  directions of your dreams,live the life you have imagined!Just do it!
It is no use learning without thinking!
2007-03-13 23:33
wfpb
Rank: 6Rank: 6
等 级:贵宾
威 望:29
帖 子:2188
专家分:0
注 册:2006-4-2
收藏
得分:0 
11楼的很经典

[glow=255,red,2]wfpb的部落格[/glow] 学习成为生活的重要组成部分!
2007-03-14 00:06
yuyunliuhen
Rank: 6Rank: 6
等 级:贵宾
威 望:20
帖 子:1435
专家分:0
注 册:2005-12-12
收藏
得分:0 

VC++与gcc在异常处理方面有什么不同?
---------------------------------------------------------------

在对Exception specifications的支持上,VC7.1和gcc不同
Microsoft Visual C++ 7.1 ignores exception specifications unless they are empty!
Empty exception specifications are equivalent to __declspec(nothrow), and they can help the compiler to reduce code size.

如下代码:
#include <iostream>
#include <exception>
using namespace std;

class error{
};

void my_unexpected()
{
cout << "unexpected exception thrown" << endl;
exit(0);
}

void f() throw(error)
{
throw 10;
}

int main( )
{
set_unexpected(my_unexpected);

try {
f();
} catch (int) {
cout << "int caught" << endl;
}
}

gcc3.3.3的输出是unexpected exception thrown
VC7.1和VC8.0Beta2的输出是int caught
VC中不会调用unexpected()
为此VC中还给出警告:C++ exception specification ignored except to indicate a function is not __declspec(nothrow)


Go confidently in the  directions of your dreams,live the life you have imagined!Just do it!
It is no use learning without thinking!
2007-03-14 23:35
yuyunliuhen
Rank: 6Rank: 6
等 级:贵宾
威 望:20
帖 子:1435
专家分:0
注 册:2005-12-12
收藏
得分:0 

返回对象和返回对象的引用有区别吗?


Mytime operator*(double i ) const
Mytime& operator*(double i ) const

返回 有什么区别?

是不返回对象要先copy 出一个临时的对象 再返回 然后释放临时对象?

Mytime operator *( double i ) const // 生成临时对象
Mytime& operator *( double i ) const // 不生成临时对象
就算返回指针也是一样.return *this没什么特别的.

"返回局部对象,可能对象已经销毁,因而获得的对象可能已不存在了,此外,开销也比较大
而返回引用开销要小,可以通过引用输入来返回"
----我的理解是,"返回局部对象的引用",虽然速度快,但是可能对象已经销毁,因而获得的对象可能已不存在了;而"返回局部对象",因为生成临时对象,所以是安全的.当然,危险也是存在的,比如在函数中用函数中char p[] = "hello world" ; return p ;虽然生成了p的临时对象,但是p所指向的内存已经销毁了.


Go confidently in the  directions of your dreams,live the life you have imagined!Just do it!
It is no use learning without thinking!
2007-03-14 23:40
yuyunliuhen
Rank: 6Rank: 6
等 级:贵宾
威 望:20
帖 子:1435
专家分:0
注 册:2005-12-12
收藏
得分:0 

this指针有什么用法?
---------------------------------------------------------------

this指针就是指向本class的对象的指针。
String & operator=(const String &rhs)
{
if (this != &rhs) {
delete「」 data;
。。。
strcpy(data、rhs。data);
}
return this;
}


class a{
public:
void test()
{
this->na = 0;
}
int na;
};
a *a1 = new a();
a1->test(); this==a1 , a1->na=0;

例如一个Ball类,你生成一个Ball的对象:
Ball myball;

那么this就是指myball

类中调用方法都会隐式加一个this指针

this就是对象的地址,相当于是*const型指针。
在调用类成员函数时,会把this存在寄存器里,以便在成员函数中使用成员变量。
this相当于成员函数的一个隐身参数,通过寄存器传递。

class A{
void fun()
{
a = 0; //等价于this->a = 0;
}
int a ;
};

this指针用于显示的引用对象的成员,只要调用成员函数,编译器就会把调用这个函数的对象的地址赋给this指针。


Go confidently in the  directions of your dreams,live the life you have imagined!Just do it!
It is no use learning without thinking!
2007-03-14 23:44
yuyunliuhen
Rank: 6Rank: 6
等 级:贵宾
威 望:20
帖 子:1435
专家分:0
注 册:2005-12-12
收藏
得分:0 

namespace没有名字有什么用?
比如
namespace
{
int iValue;
}
这里匿名 namespace 有什么作用?
---------------------------------------------------------------

回答:

C++中采用的是单一的全局变量命名空间。在这单一的空间中,如果有两个变量或函数的名字完全相同,就会出现冲突。当然,你也可以使用不同的名字,但有时我们并不知道另一个变量也使用完全相同的名字;有时为了程序的方便,必需使用同一名字。比如你定义了一个变量string user_name, 有可能在你调用的某个库文件或另外的程序代码中也定义了相同名字的变量,这就会出现冲突。命名空间就是为解决C++中的变量、函数的命名冲突而服务的。解决的办法就是将你的strTemp变量定义在一个不同名字的命名空间中。就好像张家有电视机,李家也有同样型号的电视机,但我们能区分清楚,就是因为他们分属不同的家庭。

例如:

#include <iostream>
#include <string>
using namespace std;


//using namespace编译指示,使在C++标准类库中定义的名字在本程序中可以使用
//否则,iostream,string 等c++标准类就不可见了,编译就会出错。

//两个在不同命名空间中定义的名字相同的变量

namespace myown1{

string user_name = "myown1";
}
namespace myown2{

string user_name = "myown2";
}

int main()
{
cout<< "\n"
<< "Hello, "
<< myown1::user_name //用命名空间限制符myown1访问变量user_name
<< "... and goodbye!\n";

cout<< "\n"
<< "Hello, "
<< myown2::user_name //用命名空间限制符myown2访问变量user_name
<< "... and goodbye!\n";

return 0;
}

当然,我们也可以使用程序开头的预编译指示来使用命名空间中的名字。使用预编译指示的好处在于在程序中不必显式地使用命名空间限制符来访问变量。以上主程序可修改为:
int main()
{
using namespace myown1;
cout<< "\n"
<< "Hello, "
<< user_name
<< "... and goodbye!\n";

// using namespace myown2;
cout<< "\n"
<< "Hello, "
<< myown2::user_name //用命名空间限制符myown2访问变量user_name
<< "... and goodbye!\n";

return 0;
}

但第二个变量必需用命名空间限制符来访问,因为此时myown1空间中的变量已经可见,如果不加限制,编译器就会无法识别是那一个命名空间中的变量。这一点一定要注意。 以上只是初学者不清楚的一个概念,在以后的文章中还将继续讨论其它的一些概念。
---------------------------------------------------------------

在一个名字空间里包含一系列的声明以便简单的保证有可能发生的名字冲突是非常有用的。也就是说,名字空间的目的就是保证代码的本地化而不是给用户提供接口。例如:
#include "cizi.h"
namespace CIZI{
int a;
void f() {}
int g() {}
}

既然我们不想让名字CIZI在本文件以外被知道,那么就没有必要创建一个多余的全局名字,并且这个全局名字CIZI有可能会和其他文件的名字发生冲突。在这种情况下,我们可以简单的使得这个名字空间没有名字。
#include "cizi.h"
namespace {
int a;
void f() {}
int g() {}
}

很明显,这里必定有一些方法可以访问这个没有命名的名字空间的成员。因此,没有名字的名字空间可以通过using-directive来访问,也就是说上边这个没有名字的名字空间可以和下边的定义一样。
namespace $$${
int a;
void f() {}
int g() {}
}
using namespace $$$;
在这里,$$$就是和合这个没有名字的名字空间唯一对应的名字。in particular,没有名字的名字空间,在不同的文件里是不同的。如我们希望的那样,没有任何方法可以访问其他translation unit里边的没有名字的名字空间的成员。

namespace {
namespace-body
}等价于下面的形式
<====================>
namespace unique {
/* empty body*/
}
using namespace unique;
namespace unique {
namespace-body
}


Go confidently in the  directions of your dreams,live the life you have imagined!Just do it!
It is no use learning without thinking!
2007-03-14 23:48
yuyunliuhen
Rank: 6Rank: 6
等 级:贵宾
威 望:20
帖 子:1435
专家分:0
注 册:2005-12-12
收藏
得分:0 

在多重继承中,虚函数表的结构是怎么样的?

例如一个典型的菱形继承:
class A
{
int a;
virtual void func1();
};

class A1: public A
{
int a1;
virtual void func2();
};

class A2: public A
{
int a2;
virtual void func3();
};

class B: public A1, public A2
{
int b;
virtual void func4();
};

请问类B的布局结构和它虚函数表的结构。
---------------------------------------------------------------
class Base
{
public:
virtual ~Base() ;
virtual void f1();
virtual void f2();
virtual void f3();

};
那么 Base中虚表内的函数指针分布如下
Base’s VTBL:
1--------------------------à Base::~Base()
2---------------------------> Base::f1()
3--------------------------à Base::f2()
4--------------------------à Base::f3()
如果有Derived继承于Base则在继承类中的VTBL的分布:所有虚函数指针位置按照声明先后依次拍放完毕至第一个出现被Derived覆盖的虚函数位置,然后拍放从类继承下来的虚函数(覆盖后位置不变)然后拍放后面的虚函数。
class Derived:public Base
{
public:
virtual ~Derived();
virtual void f0();
virtual void f2();
virtual void f4();

};

那么在Derived中位置拍放如下
1----------------------------à Derived::~Derived()
2----------------------------à Derived::f0()
3----------------------------à Base::f1() //基类的virtual函数
4----------------------------à Derived::f2()//覆盖后的
5----------------------------à Base::f3()
6----------------------------à Derived::f4()

每个类中只要有virtual函数存在就会产生一张虚表,如果很多这样的类VTBL也会站用不少的资源哦。这么多VTBL我们怎么处理它的放置位置呢?我记得不清楚了好象叫探勘还是勘探法的:将VTBL放在内含非内联,非纯虚的虚函数的声明的位置处。

VTBL 一般紧靠在 成员后面
virtual函数一般顺序放置在VTBL
处于VTBL的起始(不过好象保留了两位空间好象在表首)



Go confidently in the  directions of your dreams,live the life you have imagined!Just do it!
It is no use learning without thinking!
2007-03-14 23:54
快速回复:C++ FAQ from CSDN
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.012967 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved