??xml version="1.0" encoding="utf-8" standalone="yes"?> C++ 中的变量cd与Java很相伹{像Java一PC++ ?tt>int ?double cd。但是这些数字类型的取D围是依赖于机器的。比如在16位系l上Q例如运行DOS 或Windows 3.x的PCZQ?tt>int 是双字节(2-byte)的,取D围比Java?-byte?tt>int 要小很多。在q些机器上,如果 int 不够用的话,你需要用长整型long?/p>
C++ ?short ?unsigned cd来更有效的存储数字。(我认为所谓有效是指更高的I间利用率。) 最好是量避免使用q些cd除非是空间利用的有效性对你的pȝ真的非常重要?/p>
在C++中布型?bool 表示Q而不像在Java中用boolean?/p>
C++ 中字W串cd?string 表示。它与Java中的 String cd非常怼Q但是,q是要逐一以下几点不同之处Q?/p>
1. C++ 字符串存储ASCII 码字W,而不是标准码Unicode 字符 2. C++ 字符串是可以被修改的Q而Java字符串的内容是不可修改的(immutable)?/p>
3. 取子字符串的操作?C++ 中叫?substrQ这个命?tt>s.substr(i, n) 从字W串s中取得从位置 i 开始长度ؓn的子字符丌Ӏ?/p>
4. 在C++中,你只能够字W串与其它字W串对象怸?concatenate)Q而不能够与Q意的对象怸联?/p>
5. C++中可以直接用关pL作符 ==?!=?<?<=?>?>= 来进行字W串比较Q其中后面四个操作符是按字母序q行比较的?q比Java中用函数equals和compareTo来比较要方便很多?/p>
在C++中,本地变量的定义看h与Java中相同,例如Q?/p>
int n = 5; 实际上这正是C++和Java的一个重要不同之处。C++~译器不Ҏ地变量进行初始化验,所以在C++中很Ҏ忘记初始化一个变量,q种情况下,变量的D变量所占内存区域中刚好当前存在随机倹{这昄是很Ҏ产生E序出错的地斏V?/p>
与Java一P C++中类可以有数据域和静态变量。不同的是,C++中变量可以在函数甚至是类的外面定义,q些所谓的全局变量可以在程序的M函数中被讉KQ因而不易被很好的管理。所C++中应该尽量避免用全局变量?/p>
在C++中,帔R可以在Q何地方被定义Q记得在Java中,帔R必须是类的静态数据static data)?C++ 使用关键?const 来定义常量,而Java中是 final。例如: const int DAYS_PER_YEAR = 365; C++ 中对cȝ定义与Java有些不同Q这里是一个例子:一个C++ 版本?Point c? class Point /* C++ */ { public: Point(); Point(double xval, double yval); void move(double dx, double dy); double getX() const; double getY() const; private: double x; double y; }; q里几点重要的不同是Q?/p>
1. C++的类定义中分为公共和U有部分Q分别以关键?public ?private开始。而在Java中,每一个元素都必须标明 public ?private?/p>
2. C++中类的定义只包含函数的声明,真正的实现另外单独列出?/p>
3. 讉K函数(accessor methods)标有关键?const Q表明这个函C会改变本对象的元素倹{?/p>
4. cd义的l尾处有分号 cM函数的实现跟在类的定义之后。因为函数是在类外面定义的,所以每一个函数的名字前面要加cdUC为前~Qƈ使用操作W双冒号::来分割类的名U和函数的名U。不改变隐含参数|卛_前对象的|的访问函数用 const标明。如下所C是上面cd义中的函数的实现Q?/p>
Point::Point() { x = 0; y = 0; } void Point::move(double dx, double dy) { x = x + dx; y = y + dy; } double Point::getX() const { return x; } Java ?C++ 最主要的不同在于对象变量的使用。在 C++中,对象变量存储的是真正的对象的|而不是对象引?reference)。注意在C++中构造一个对象的时候是不用关键字new的,只需要在变量的名字后面直接赋予构造函数的参数可以了Q例如: Point p(1, 2); /* 构造对?p */ 如果不跟参数赋|则用默认构造函敎ͼ例如Q?/p>
Time now; /* 默认使用构造函?Time::Time() */ q一点与Java很不同。在Java中,q个命o仅仅生成一个没有初始化的referenceQ而在C++中,它生成一个实际的对象?/p>
当一个对象被赋给另一个对象变量的时候,实际的值将被拷贝。而在Java中,拯一个对象变量只不过是徏立了另外一个指向对象的reference。拷贝一个C++的对象就像在Java中调用cloneq个函数一P而修Ҏ贝的g会改变原对象的倹{例如: Point q = p; /* 拯p到q */ q.move(1, 1); /* Udq而p不动Q即q的值变了,而p的不?/ 多数情况下,C++中这U对象直接对值操作的Ҏ用v来很方便Q但是也有些时候不如人意Q?/p>
1. 当需要一个函C修改一个对象的|必须C要用按引用调用call by reference (参见下面函数部分) 2. 两个对象变量不能指向同一个对象实体。如果你要在C++中实现这U效果,必须使用指针pointerQ参见下面指针部分) 3. 一个对象变量只能存储一U特定的cd的|如果你想要用一个变量来存储不同子类的对象的|多态ploymorphism)Q则需要用指针?/p>
4. 如果你想在C++中用一个变量来或者指向null或者指向一个实际的对象Q则需要用指?/p>
在Java中,每一个函数必L者是对象函数(instance method)Q或者是静态函?static function)或称cd数。C++同样支持对象函数和静态函敎ͼcd敎ͼQ但同时C++也允许定义不属于Mcȝ函数Q这些函数叫做全局函数Qglobal functionsQ?/em>?/p>
特别的是Q每一个C++ E序都从一个叫?main的全局函数开始执行: int main() { . . . } q有另外一个格式的main函数可以用来捕捉命o行参敎ͼcM于Java的main函数Q但是它要求关于C格式的数l和字符串的知识Q这里就不介l了?/p>
按照习惯Q通常如果E序执行成功Q?main 函数q回0Q否则返回非零整数?/p>
同Java一P函数参数是通过g递的(passed by value)。在Java中,函数无论如何都是可以修改对象的值的。然而在C++中,因ؓ对象直接存储的是实际的|而不是指向值的referenceQ也是说传入函数的是一个实际值的拯Q因此也无法修改原来对象的倹{?/p>
所以,C++ 有两U参C递机Ӟ同Java一L按D?call by value) Q以及按地址调用(call by reference)。当一个参数是按reference传递时Q函数可以修改其原始倹{Call by reference 的参数前面有一个地址?& 跟在参数cd的后面,例如Q?/p>
void raiseSalary(Employee& e, double by) { . . . } 下面是一个典型的利用call by reference的函敎ͼ在Java中是无法实现q样的功能的?/p>
void swap(int& a, int& b) { int temp = a; a = b; b = temp; } 如果使用 swap(x, y)来调用这个函敎ͼ则reference参数 a ?b 指向原实际参?tt>x ?y的位|,而不是它们的值的拯Q因此这个函数可以实现实际交换这两个参数的倹{?/p>
?C++中,每当需要实C改原参数的值时你就可以使用按地址调用 call by reference C++ 的向量结构结合了Java中数l和向量两者的优点。一个C++ 的向量可以方便的被访问,其容量又可以动态的增长。如?T 是Q意类型,?vector<T> 是一个元素ؓ T cd的动态数l。下面的语句 vector<int> a; 产生一个初始ؓI的向量。而语?/p>
vector<int> a(100); 生成一个初始有100个元素的向量。你可以使用push_back 函数来添加元素: a.push_back(n); 调用 a.pop_back() ?tt>a中取出最后一个元素(操作后这个元素被从a中删?Q?使用函数size 可以得到当前a中的元素个数?/p>
你还可以通过我们熟悉?[] 操作W来讉K向量中元素,例如Q?/p>
for (i = 0; i < a.size(); i++) { sum = sum + a[i]; } 同Java中一P数组索引必须?0 ?a.size() - 1之间的倹{但是与Java不同的是QC++中没有runtime的烦引号合法性检验。试图访问非法的索引位置可能造成非常严重的出错?/p>
像所有其?C++ 对象一P向量也是倹{如果你一个向量赋值给另外一个向量变量,所有的元素都会被拷贝过厅R?/p>
vector<int> b = a; /* 所有的元素都被拯?*/ ҎJava中的情况Q在Java中,一个数l变量是一个指向数l的reference。拷贝这个变量仅仅生另外一个指向同一数组的referenceQ而不会拷贝每一个元素的倹{?/p>
正因如此Q如果一个C++函数要实C改向量的|必须使用reference参数Q?/p>
void sort(vector<int>& a) { . . . } 在C++中,标准的输入输出流用对?cin ?cout 表示。我们?<< 操作W写输出Q例如: cout << “Hello, World!”; 也可以连着输出多项内容Q例如: cout << “The answer is ” << x << “\n”; 我们使用 >> 操作W来d一个数字或单词Q例如: double x; cout << “Please enter x: “; cin >> x; string fname; cout << “Please enter your first name: “; cin >> fname; 函数getline 可以d整行的输入,例如Q?/p>
string inputLine; getline(cin, inputLine); 如果到达输入的结,或者一个数字无法被正确的读入,q个对象会被设|ؓ failed 状态,我们可以使用函数 fail 来检验这个状态,例如Q?/p>
int n; cin >> n; if (cin.fail()) cout << “Bad input”; 一旦一个流的状态被设ؓfailedQ我们是很难重置它的状态的Q所以如果你的程序需要处理错误输入的情况Q应该用函?getline 然后人工处理得到的输入数据?/p>
我们已经知道在C++中,对象变量直接存储的是对象的倹{这是与Java不同的,在Java中对象变量存储的是一个地址Q该地址指向对象值实际存储的地方。有时在C++中也需要实现这L布置Q这qC指针pointer。在 C++中,一个指向对象的变量叫做指针。如果T是一U数据类型,?T* 是指向这U数据类型的指针?/p>
像 Java中一P一个指针变量可以被初始化ؓI?NULLQ另外一个指针变量的|或者一个调用new生成的新对象Q?/p>
Employee* p = NULL; Employee* q = new Employee(”Hacker, Harry”, 35000); Employee* r = q; 实际上在C++中还有第四种可能Q那是指针可以被初始化为另外一个对象的地址Q这需要用地址操作W?& Q?/p>
Employee boss(”Morris, Melinda”, 83000); Employee* s = &boss; q实际上q不是什么好L。保险的做法q是应该直接让指针指向?new生成的新对象?/p>
到目前ؓ止,C++ 指针看v来非常像 Java 的对象变量。然而,q里有一个很重要的语法的不同。我们必M用星h作符 * 来访问指针指向的对象。如?p 是一个指?tt>Employee对象的指针,?*p 才代表了q个对象Q?/p>
Employee* p = . . .; Employee boss = *p; 当我们需要执行对象的函数或访问对象的一个数据域Ӟ也需要?*p Q?/p>
(*p).setSalary(91000); *p外面的括h必需的,因ؓ . 操作W比 * 操作W有更高的优先。C的设计者觉得这U写法很隄Q所以他们提供了另外一U替代的写法Q?-> 操作W来实现 * ?. 操作W的l合功能。表辑ּ p->setSalary(91000); 可以调用对象*p的函?setSalary 。你可以单的C . 操作W是在对象上使用的,-> 操作W是在指针上使用的?/p>
如果你不初始化一个指针,或者如果一个指针ؓI?NULL 或指向的对象不再存在Q则在它上面使用 * ?-> 操作W就会出错?不幸的是 C++ runtime pȝq不查这个出错。如果你范了q个错误Q你的程序可能会行ؓ古怪或L?/p>
而在Java中,q些错误是不会发生的。所有的reference都必d始化Q所有的对象只要仍有reference指向它就不会被从内存中清除,因此你也不会有一个指向已被删除的对象的reference。Java的runtime pȝ会检查reference是否为空Qƈ在遇到空指针时抛Z个null pointer的例?exception)?/p>
C++ ?Javaq有一个显著的不同Q就?Java ?em>垃圾回收 C++中当对象变量出范围时可以自动被回收。但是用new生成的对象必ȝdelete操作W手动删除,例如Q?/p>
Employee* p = new Employee(”Hacker, Harry”, 38000); . . . delete p; /* 不在需要这个对?*/ 如果你忘记删除一个对象,那么你的E序有可能最l用光所有内存。这是我们常说的内存泄?(memory leak)。更重要的是Q如果你如果删除了一个对象,然后又l用它Q你可能覆盖不属于你的数据。如果你刚y覆盖了用于处理内存回收的数据域,那么内存分配机制可能运转失常而造成更严重的错误Q而且很难诊断和修复。因此,在C++中最好尽量少用指?/p>
C++和Java中承的基本语法是很怼的。在C++中,使用 : public 代替Java中的extends 来表C承关p??(C++ 也支持私有承的概念Q但是不太有用? 默认情况下,C++中的函数不是动态绑定的。如果你需要某个函数实现动态绑定,需要?tt>virtual声明它ؓ虚函敎ͼ例如Q?/p>
class Manager : public Employee { public: Manager(string name, double salary, string dept); virtual void print() const; private: string department; }; 同Java一P构造函C调用父类的构造函数有Ҏ的语法?Java使用关键?super。C++中必d子类的构造函C外调用父cȝ构造函数。下面是一个例子: Manager::Manager(string name, double salary, string dept) : Employee(name, salary) /* 调用父类的构造函?*/ { department = dept; } Java 中在子类函数中调用父cȝ函数时也使用关键?super 。而在C++中是使用父类的名U加上操作符 ::表示Q例如: void Manager::print() const { Employee::print(); /* 调用父类的函?*/ cout << department << “\n”; } 一?C++ 对象变量只能存储特定cd的对象倹{要惛_C++中实现多?polymorphism)Q必M用指针。一?T* 指针可以指向cd?T ?T 的Q意子cȝ对象Q例如: Employee* e = new Manager(”Morris, Melinda”, 83000, “Finance”); 你可以将父类和不同子cȝ对象混合攉C个元素均为指针的向量中,然后调用动态绑定的函数Q如下所C: vector<Employee*> staff; . . . for (i = 0; i < staff.size(); i++) staff[i]->print();
]]>
]]>
const char* str = "ss" ;
this->SetDlgItemTextW(IDC_MyLable, (LPCTSTR)str);
]]>
Visual C++ 6.0 体中文企业版 集成SP6完美?/font>
Visual C++ 6.0 英文企业?集成SP6完美?/font>
Visual Studio 6.0 英文企业?集成SP6完美?/font>
C语言:
谭浩强C语言教程全书 Word?/font>
C语言味E序百例_解
Sams出版 Advanced C 高C语言开?
C数值算法程序大?
C语言专家~程
C语言E序设计案例_
C语言q阶
C Primer Plus [SAMS]
C Pocket Reference [O'Reilly]
Practical C Programming
The C Programming Language
吉林大学C语言视频教程 ?1?CSF格式
C语言基础视频教程 ?4?完整上架
C语言E序设计视频教程 曾怡教授讲??8讲完整版下蝲
数据l构视频教程 清华大学严蔚敏主??8?完整?ASF格式
数据l构C语言版视频教E??2讲完整版
C++:
p c++E序设计教程 W二?高清PDF?/font>
Essential C++ 中文?英文?侯捷?
~程炚w之Visual C++(电子教程) iso
C++E序调试实用手册
C++面向对象多线E编E?/font>
C++高~程参考手?/font>
C++ Primer W三?/font>
C++ Primer W四?中文版高清晰
C和C++代码_a
C++沉思录
高质量C++~程指南
C++ ~程思想 W??标准C++导引
C++ ~程思想 W??实用~程技?/font>
More Effective C++ 体中文版
C++ Templates 中文?英文?/font>
C++ Coding Standards[Addison Wesley]
Absolute C++ 全彩代码剖?/font>
Accelerated C++ - Practical Programming by Example
Inside the C++ Object Model
More Exceptional C++ [Addison Wesley]
Exceptional C++ [Addison Wesley]
Sams出版 C++ Unleashed
C++ GUI Programming with QT4
VC++深入详解 孙鑫作品pd 高清PDF版下?/font>
Visual C++ 6ȝ?快速参?
Visual C++ 6.0 ~程实例与技?PDF中文?
Visual C++ 21天自学教E?
跟我学Visual C++ 6
Visual C++ 6 数据库编E?21天自学教E?CHM
The C++ Programming Language W三?
深度探烦C++对象模型
Special Edition Using Visual C++ 6
Professional MFC with VC 6
Practical C++ Programming
Cross-Platform Development in C++
Iterative UML Development Using VC++ 6
Ace Programmer's Guide
Visual C++高界面Ҏ制作百例
_NGDI+~程 清华大学出版
Borland C++ Builder 6 开发指?CHM
孙鑫C++视频教程 rmvb格式 ?0CD完整?/font>
C++E序设计视频教程 东南大学何洁月主??0?? 48?/font>
C++E序设计视频教程 东南大学何洁月主??0?? 32?/font>
C++视频教程 边用边学Visual C++ 6 (ASF格式)
中山大学蔡培?C++语言视频教程 ?1?_֓推荐
]]>
]]>
]]>
我有个Button1、Button2在From1中,另外有个Button3在Form2?
现在我在button1_Click中加入Form2^ Form2Dlg=gcnew Form2(); Form2Dlg->ShowDialog(this);
现在我想昄Form2后我按Button3后能响应Button2的Click事g怎么搞了Q?img src ="http://www.shnenglu.com/smallfa/aggbug/106544.html" width = "1" height = "1" />
]]>
2. 变量和常?/h2>
3. c?/h2>
4. 对象
5. 函数
6. 向量Vector
7. 输入和输?/h2>
8. 指针pointer
9. l承
]]>
{
d = (day)(d + 1);
return d;
}
使用q个函数Q?表达?++x 才有正确的显CZ及正的操作?br>Passing by reference不仅仅是写operator++较好的方法,而是唯一的方法?br>
C++在这里ƈ没有l我们选择的余地?br> 像下面的声明:
day *operator++(day *d);
是不?通过~译的?br>每个重蝲的操作符函数必须或者是一个类的成员, 或者用类型T?T & ?T const & 为参数类型,
q里T是一个类(class)或列?enumeration)cd?
也就是说Q每一个重载操作符必须以类或列丄型ؓ参数cd?br>
指针Q即使是指向一个类或列丄型对象的指针Q也不可以用?br>
C++ 不允许在重蝲操作W时重新定义内置操作W的含义Q包括指针类型?br>因此Q我们不可以定义Q?br>int operator++(int i); // 错误
因ؓ它试囑֯int重新定义操作W?++ 的含义?我们也不可以定义Q?br>int *operator++(int *i); // 错误
因ؓ它试囑֯ int * 重新定义操作W?++ 的含?br>
C++ 中不允许定义”const reference”Q?br> 因ؓ一个reference天生是const。也是_一旦将一个referencel定C个对象,无法再它重新l定到另一个不同的对象?br>在声 明一个reference之后没有写法可以它重新l定到另外一个对象?br>例如Q?br>int &ri = i;
?ri l定?i 。然后下面的赋?
ri = j;
q不是把 ri l定?j Q而是?j 中的Dl?ri 指向的对象,也就是赋l?i ?br>
而言之,
一个pointer在它的有生之q可以指向许多不同的对象Q?br>而一个reference只能够指向一个对象?br>有些才是 reference?pointer最大的不同?br>我ƈ不赞成。也许这是reference与pointer的一点不同, 但ƈ不是reference和const pointer的不同?br>在强调一遍,一旦一个reference与一个对象绑定,׃能再它Ҏ向另外的东西?br>既然不能再绑定reference之后?改变Q?一个reference必d一出生pl定?br>否则q个reference永q不能被l定CQ何东西,也就毫无用处了?/p>
上一D늚讨论也同样完全适用于常量指针(const pointerQ?br>Q注意,我这里说的是帔R指针Qconst pointerQ, 而不是指向常量的指针 “pointers to const”?
例如Q?br>一个reference声明必须同时带有一个初始化赋|如下所C:
void f()
{
int &r = i;
…
}
省略q个初始化赋值将产生一个编译错误:
void f()
{
int &r; //错误
…
}
一个常量指针的声明也同样必d有一个初始化赋|如下所C:
void f()
{
int *const p = &i;
…
}
省略q个初始化赋值同样会出错Q?/p>
void f(){
int *const p; // 错误
…
}
在我看来
不能够对reference二次l定作ؓreference与pointer的不同?br>q不比常量指针和非常量指针的不同更ؓ显著?br>
除了昄的不同,帔R指针与referenceq有一炚w怸同,那就是,一个有效的reference必须指向一个对象;而一个指针不需要。一个指针,即是一个常量指针, 都可以有I倹{?一个空指针不指向Q何东ѝ?/p>
q点不同暗C当你想要确信一个参数必L向一个对象的时候,应该使用reference作ؓ参数cd?例如Q交换函?swap function)Q它接受两个int参数Qƈ两个参数的数值对调,如下所C:
int i, j;
swap(i, j);
原本在 i 中的值放?j 中, q将原本?j 中的值放?i 中。我们可以这样写q个函数Q?/p>
void swap(int *v1, int *v2)
{
int temp = *v1;
*v1 = *v2;
*v2 = temp;
}
q种定义下,函数要像q样被调? swap(&i, &j);
q个接口暗示其中一个或两个参数都有可能为空(null)。而这个暗C是误导的。例如,调用
swap(&i, NULL);
的后果很可能是不愉快的?/p>
而像下面q样定义reference为参敎ͼ
void swap(int &v1, int &v2)
{
int temp = v1;
v1 = v2;
v2 = temp;
}
清晰的表明了调用swap应该提供两个对象Q它们的值将被交换?q且q样定义的另一个好处是Q在调用q个函数的时候,不需要用那?amp;W号Q看h更顺|
swap(i, j);
除了昄的不同,
帔R指针与referenceq有一炚w怸同,
那就是,一个有效的reference必须指向一个对象;
?span style="COLOR: red">一个指针不需?/span>?br>一个指针,即是一个常量指针, 都可以有I倹{?一个空指针不指向Q何东ѝ?br>
q点不同暗C当你想要确信一个参数必L向一个对象的时候,应该使用reference作ؓ参数cd?/span>
例如Q?br>交换函数(swap function)Q它接受两个int参数Qƈ两个参数的数值对调,如下所C:
int i, j;
swap(i, j);
原本在 i 中的值放?j 中, q将原本?j 中的值放?i 中。我们可以这样写q个函数Q?/p>
void swap(int *v1, int *v2)
{
int temp = *v1;
*v1 = *v2;
*v2 = temp;
}
q种定义下,函数要像q样被调? swap(&i, &j);
q个接口暗示其中一个或两个参数都有可能为空(null)。而这个暗C是误导的。例如,调用
swap(&i, NULL);
的后果很可能是不愉快的?/p>
而像下面q样定义reference为参敎ͼ
void swap(int &v1, int &v2)
{
int temp = v1;
v1 = v2;
v2 = temp;
}
清晰的表明了调用swap应该提供两个对象Q它们的值将被交换?q且q样定义的另一个好处是Q在调用q个函数的时候,不需要用那?amp;W号Q看h更顺|
swap(i, j);
有些为既然reference不能够ؓI,那么它应该比指针更安全?br> 我认为reference可能要安全一点,但不会安全很多?br>虽然一个有效的reference不能为空Q但是无效的可以呀?br>实际上,在很多情况下E序有可 能生无效的referenceQ而不只是I的reference?/span>
例如Q?/span>
你可以定义一个referenceQ它绑定到一个指针指向的对象Q如下所C:
int *p;
…
int &r = *p;
如果指针*p在reference定义时刚好ؓI,则这个reference为空?br> 从技术上来说Q这个错误ƈ不在于将referencel定C个空|而是在于对一个空指针d考?br> 对一个空指针d考生了一个不定的操作,也就意味着很多事都可能发生Q而且大部分都不是什么好事。很有可能当E序reference r l定?p (p所指向的对?的时候,p实际上没有被d考,甚至E序只是p的值拷贝给实现r的指针?br>而程序将会l执行下ȝ到错误在后面的运行中更ؓ明显的表 现出来,产生不可预知的危実?/p>
下面的函?br>展示?br>另外一U生无效reference的方法:
int &f()
{
int i;
…
return i;
}
q个函数q回一个指向本地变?i 的reference?br>然而当函数q回Ӟ本地变量 i 的存储空间也消׃。因此这个函数实际返回了一个指向被回收了的I间的reference。这个操作与q回一个指向本地变量的指针的后果相同?br>有些~译 器可以在~译时发现这个错误,但也很有可能不会发现?br>
我喜ƢreferenceQ也有很好的理由使用它们代替pointer?br>
但如果你期望使用reference来你的E序健壮性显著增强,那么你多半会失望?br>
在Visual C++中定义一般的函数为朋友函数通常是没有问题的?br>然而对某些重蝲操作W的函数Q?br>即我们它们定义ؓcȝ朋友函数QVC的编译器仍然会显C出错信息,
认ؓq些朋友函数无权讉KcȝU有成员?br>我认应该是VC6.0的bug?br>
以下代码是个例?
// 头文?“Sample.h” #include<iostream> using namespace std; class Sample { public: Sample(); friend ostream &operator<<(ostream &out, const Sample s); friend istream &operator>>(istream &in, Sample & s); private: int x; }; |
// 实现文g “Sample.cpp” #include “Sample.h” Sample::Sample() { x=0; } istream &operator>>(istream &in, Sample & s) { cout<<”Please enter a value”<<endl; in >> s.x ; return in; } ostream &operator<<(ostream &out, const Sample s) { cout << s.x << endl; return out; } |
以上代码在gnuc++中编译运行毫无问题。但是在VC++6.0中编译的时候就会出C下的~译错误Q?/p>
Compiling… Sample.cpp c:\temp\sample.cpp(8) : error C2248: ‘x’ : cannot access private member declared in class ‘Sample’ c:\temp\sample.h(19) : see declaration of ‘x’ c:\temp\sample.cpp(13) : error C2248: ‘x’ : cannot access private member declared in class ‘Sample’ c:\temp\sample.h(19) : see declaration of ‘x’ Error executing cl.exe.Sample.obj - 2 error(s), 0 warning(s) |
在VC++ 6.0中解册个问题有以下几种ҎQ?/p>
// 修改后的头文?1 “Sample.h” #include<iostream> using namespace std; class Sample { public: Sample(); friend ostream &operator<<(ostream &out, const Sample s); friend ostream &operator<<(ostream &out, const Sample s) { cout << s.x << endl; return out; } friend istream &operator>>(istream &in, Sample & s); friend istream &operator>>(istream &in, Sample & s) { cout<<”Please enter a value”<<endl; in >> s.x ; return in; } private: int x; }; |
// 修改后的头文?2 “Sample.h”
#include<iostream>
using namespace std;
// 以下3行代码ؓ新加?
class Sample;
ostream &operator<<(ostream &out, const Sample s);
istream &operator>>(istream &in, Sample & s);
class Sample {
public:
Sample();
friend ostream &operator<<(ostream &out, const Sample s);
friend istream &operator>>(istream &in, Sample & s);
private:
int x;
};
|
// Sample.h
#include<iostream>
using std::istream;
using std::ostream;
class Sample {
public:
Sample();
friend ostream &operator<<(ostream &out, const Sample s);
/*friend ostream &operator<<(ostream &out, const Sample s) {
cout << s.x << endl;
return out;
}*/
friend istream &operator>>(istream &in, Sample & s);
/*friend istream &operator>>(istream &in, Sample & s) {
cout<<”Please enter a value”<<endl;
in >> s.x ;
return in;
}*/
private:
int x;
};
|
// “Sample.cpp” #include “Sample.h” using namespace std; Sample::Sample() { x=5; } istream &operator>>(istream &in, Sample & s) { cout<<”Please enter a value”<<endl; in >> s.x ; return in; } ostream &operator<<(ostream &out, const Sample s) { cout << s.x << endl; return out; } |