文档库 最新最全的文档下载
当前位置:文档库 › VC6.0中重载操作符友元函数无法访问类的私有成员的解决办法

VC6.0中重载操作符友元函数无法访问类的私有成员的解决办法

VC6.0中重载操作符友元函数无法访问类的私有成员的解决办法
VC6.0中重载操作符友元函数无法访问类的私有成员的解决办法

VC6.0中重载操作符友元函数无法访问类的私有成员的解决办法

VC6.0中重载操作符友元函数无法访问类的私有成员的解决办法:

在C++中,操作符(运算符)可以被重载以改写其实际操作。

同时我们可以定义一个函数为类的友元函数(friend function)以便使得这个函数能够访问类的私有成员,这个定义通常在头文件中完成。

在Visual C++中定义一般的函数为友元函数通常是没有问题的。然而对某些重载操作符的函数,即使我们将它们定义为类的友元函数,VC的编译器仍然会显示出错信息,认为这些友元函数无权访问类的私有成员。我认为这应该是VC6.0编译器与标准C++不兼容的地方。

以下代码就是个例子:

// 头文件“Sample.h”

#include

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;

};

// 实现文件“Sample.cpp”

#include “Sample.h”

Sample::Sample( )

{

x=0;

}

istream &operator>>(istream &in, Sample & s)

{

cout<<”Please enter a value”<

in >> s.x ;

return in;

}

ostream &operator<<(ostream &out, const Sample s)

{

cout << s.x << endl;

return out;

}

以上代码在gnuc++中编译运行毫无问题。但是在VC++6.0中编译的时候就会出现以下的编

译错误:

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中解决这个问题有以下几种方法:

第一种方法:在头文件中类定义之前将类和友元操作符函数的原型特别声明一下,也就是将头文件修改如下(实现文件”Sample.cpp”不用作任何修改):

// 修改后的头文件2 “Sample.h”

#include

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.cpp”中将函数重载的实现去掉,而将头文件修改如下:

// 修改后的头文件1 “Sample.h”

#include

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)

{

cou t<<”Please enter a value”<

in >> s.x ;

return in;

}

private:

int x;

};

第三种方法:是对I/O名空间的使用实行明确声明,也就是说在头文件”Sample.h”中直接写:#include

using std::ostream;

using std::istream

….

取代“using namespace std;”

注意:在这个例子里我们在实现文件“Sample.cpp”中包含“using namespace std;”这句话,否则在实现中就不能使用“cout”, “cin”, “<< “, “>>”和endl 这些关键字和符号。修改后的完整代码如下:

// Sample.h

#include

using std::istream;

using std::ostream;

class Sample

{

public:

Sample( );

friend ostream &operator<<(ostream &out, const Sample s);

friend istream &operator>>(istream &in, Sample & s);

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”<

in >> s.x ;

return in;

}

ostream &operator<<(ostream &out, const Sample s) {

cout << s.x << endl;

return out;

}

函数重载习题与解析

++习题与解析-重载 时间:2010-05-19 12:13:47 来源:第二电脑网作者:第二电脑网 第二电脑网导读:t< int add(int x,int y) { return x+y; } double add(double x,double y) { return x+y; } void main() { int a=4,b=6; double c=2.6,d=7.4; cout< class Sample { int i; double d; public: void setdata(int n){i=n;} void setdata(double x){d=x;} void disp() {

运算符重载练习题.

运算符重载 一.单项选择题 1.下列运算符中,运算符在C++中不能重载。 A.?: B.+ C. D.<= 解:C++中不能被重载的运算符有:·,一,::,?:。本题答案为A。 2.下列运算符中,运算符在C++中不能重载。 A.&& B.[] C.:: D.new 解:c++中不能被重载的运算符有:·,·+,::,?:。本题答案为c。 3.下列关于运算符重载的描述中,是正确的。 A.运算符重载可以改变操作数的个数 B.运算符重载可以改变优先级 C.运算符重载可以改变结合性 D.运算符重载不可以改变语法结构 解:运算符重载不能改变操作数的个数、运算符的优先级、运算符的结合性和运算程的语法结构。本题答案为D。 4.友元运算符objl>obj2被C++编译器解释为。 A.operator>(objl,obj2) B.>(obj1,obj2) C.obj2.operator:>(obj1) D.objl.operator>(obj2) 解:重载为友元函数的运算符的调用形式如下: operator<运算符>(<参数1>,<参数2>) 等价于:<参数1><运算符><参数2> 本题答案为A。 5.现需要对list类对象使用的逻辑运算符“==”重载,以下函数声明是正确的。 A、list & list::operator==(const list &a); B、list list::operator==(const list &a); C、bool & list::operator==(const list &a); D、bool list::operator==(const list &a); 6. 以下类中分别说明了“+=”和“++”运算符重载函数的原型。如果主函数中有定义: fun m,c,d;,那么,执行语句c=m++; 时,编译器把m++解释为: (33) A) c.operator++(m); B) m=operator++(m); C) m.operator++(m); D) operator++(m); class fun { public: .. .. .. fun operator +=(fun ); friend fun operator ++(fun &,int); }; 答案:D 7. 在第33题中,当执行语句d+=m; 时,C++编译器对语句作如下解释: (34) A. d=operator+=(m); B. m=operator+=(d); C. d.operator+=(m); D. m.operator+=(d); 答案:C 8. 设有以下类定义,其中说明了“+”运算符重载函数的原型。这是一个友元函数,当类

c 运算符的重载习题答案

1.概念填空题 1.1运算符重载是对已有的运算符赋予多重含义,使同一个运算符在作用于不同类型对象时导致不同的行为。运算符重载的实质是函数重载,是类的多态性特征。 1.2可以定义一种特殊的类型转换函数,将类的对象转换成基本数据类型的数据。但是这种类型转换函数只能定义为一个类的成员函数而不能定义为类的友元函数。类类型转换函数既没有参数,也不显式给出返回类型。类类型函数中必须有return 表达式的语句返回函数值。一个类可以定义多个类类型转换函数。 1.3运算符重载时其函数名由operator运算符构成。成员函数重载双目运算符时,左操作数是对象,右操作数是函数参数。 2.简答题 2.2简述运算符重载的规则。 2.2简述重载单目运算符++、--,前置和后置时的差别。 2.3 C++中重运算符是否都可以重载?是否都可以重载成类的成员函数?是否都可以重载成类的友元函数? 2.4 构造函数作为类型转换函数的条件是什么。 3.选择题 3.1在下列运算符中,不能重载的是(B) A.! B. sizeof C. new D. delete 3.2 不能用友员函数重载的是(A)。 A.= B.== C.<= D.++ 3.3下列函数中,不能重载运算符的函数是(B)。 A.成员函数 B.构造函数 C.普通函数 D.友员函数 3.4如果表达式++i*k时中的”++”和”*”都是重载的友元运算符,则采用运算符函数调用格式,该表达式还可表示为(B)。 A.operator*(i.operator++(),k) B.operator*(operator++(i),k) C.i.operator++().operator*(k) D.k.operator*(operator++(i)) 3.5已知在一个类体中包含如下函数原型:VOLUME operator-(VOLUME)const;下列关于这个函数的叙述中,错误的是(B )。 A.这是运算符-的重载运算符函数 B.这个函数所重载的运算符是一个一元运算符 C.这是一个成员函数 D.这个函数不改变数据成员的值 3.6在表达式x+y*z中,+是作为成员函数重载的运算符,*是作为非成员函数重载的运算符。下列叙述中正确的是(C )。 A.operator+有两个参数,operator*有两个参数 B.operator+有两个参数,operator*有一个参数 C.operator+有一个参数,operator*有两个参数 D.operator+有一个参数,operator*有一个参数 4.写出下列程序运行结果 4.1#include #using namesoace std;

10.5C++运算符重载函数作为类成员函数和友元函

例10.2中对运算符“+”进行了重载,使之能用于两个复数的相加。在该例中运算符重载函数operator+作为Complex类中的成员函数。 可能有的读者会提出这样的问题:”+“是双目运算符,为什么在例10.2程序中的重载函数中只有一个参数呢?实际上,运算符重载函数有两个参数,由于重载函数是Complex 类中的成员函数,有一个参数是隐含的,运算符函数是用this指针隐式地访问类对象的成员。可以看到,重载函数operator+访问了两个对象中的成员,一个是this指针指向的对象中的成员,一个是形参对象中的成员。如this->real+c2.real,this->real就是c1.real。 上节中已说明,在将运算符函数重载为成员函数后,如果出现含该运算符的表达式,如c1+c2,编译系统把它解释为: c1.operator+(c2) 即通过对象c1调用运算符重载函数,并以表达式中第二个参数(运算符右侧的类对象c2)作为函数实参。运算符重载函数的返回值是Complex类型,返回值是复数c1和c2之和(Complex(c1.real + c2.real, c1.imag+c2.imag))。 运算符重载函数除了可以作为类的成员函数外,还可以是非成员函数。可以将例10.2改写为例10.3。 [例10.3] 将运算符“+”重载为适用于复数加法,重载函数不作为成员函数,而放在类外,作为Complex类的友元函数。 .#include .using namespace std;

.// 注意,该程序在VC 6.0中编译出错,将以上两行替换为#include 即可顺利通过 .class Complex .{ .public: .Complex( ){real=0;imag=0;} .Complex(double r,double i){real=r;imag=i;} .friend Complex operator + (Complex &c1,Complex &c2); //重载函数作为友元函数 .void display( ); .private: .double real; .double imag; .}; . .Complex operator + (Complex &c1,Complex &c2) //定义作为友元函数的重载函数 .{ .return Complex(c1.real+c2.real, c1.imag+c2.imag); .} . .void Complex::display( ) .{ .cout<<"("< class Complex { private: float Real,Image; public: Complex(float r=0,float i=0) { Real=r;Image=i;} void Show(int i) { cout<<"c"<

C++函数重载

——每个现象后面都隐藏一个本质,关键在于我们是否去挖掘 写在前面: 函数重载的重要性不言而明,但是你知道C++中函数重载是如何实现的呢(虽然本文谈的是C ++中函数重载的实现,但我想其它语言也是类似的)?这个可以分解为下面两个问题 ?1、声明/定义重载函数时,是如何解决命名冲突的?(抛开函数重载不谈,using就是一种解决命名冲突的方法,解决命名冲突还有很多其它的方法,这里就不论述了)?2、当我们调用一个重载的函数时,又是如何去解析的?(即怎么知道调用的是哪个函数呢) 这两个问题是任何支持函数重载的语言都必须要解决的问题!带着这两个问题,我们开始本文的探讨。本文的主要内容如下: ?1、例子引入(现象) o什么是函数重载(what)? o为什么需要函数重载(why)? ?2、编译器如何解决命名冲突的? o函数重载为什么不考虑返回值类型 ?3、重载函数的调用匹配 o模凌两可的情况 ?4、编译器是如何解析重载函数调用的? o根据函数名确定候选函数集 o确定可用函数 o确定最佳匹配函数 ?5、总结 1、例子引入(现象) 1.1、什么是函数重载(what)? 函数重载是指在同一作用域内,可以有一组具有相同函数名,不同参数列表的函数,这组函数被称为重载函数。重载函数通常用来命名一组功能相似的函数,这样做减少了函数名的数量,避免了名字空间的污染,对于程序的可读性有很大的好处。 When two or more different declarations are specified for a single name in the same scope, that name is said to overloaded. By extension, two declaration s in the same scope that declare the same name but with different types are called overloaded declarations. Only function declarations can be overloaded; o bject and type declarations cannot be overloaded. ——摘自《ANSI C++ Standar d. P290》在线代理|网页代理|代理网页|https://www.wendangku.net/doc/1a19062593.html,

c++运算符重载习题

Task8-1 /* 1. 定义一个复数类Complex,重载运算符“+”,使之能用于复数的加法运算。将运算符函数重载为非成员、非友元的普通函数。编写程序,求两个复数之和*/ #include using namespace std; class Complex { public: Complex(){real=0;imag=0;} Complex(double r,double i){real=r;imag=i;} void display(); double real; double imag; }; void Complex::display() { cout<<"("<

static char* str; String operator+(const String& a,const String& b) { strcpy(str,https://www.wendangku.net/doc/1a19062593.html,); strcat(str,https://www.wendangku.net/doc/1a19062593.html,); return String(str); } void main() { str=new char[256]; String demo1("Visual c++"); String demo2(" 6.0"); demo1.display(); demo2.display(); String demo3=demo1+demo2; demo3.display(); String demo4=demo3+" Programming."; demo4.display(); String demo5="Programming."+demo4; demo5.display();

delete str; } 程序的运行结果为: The string is :Visual c++ The string is : 6.0 The string is :Visual c++ 6.0 The string is :Visual c++ 6.0 Programming. The string is :Programming.Visual c++ 6.0 Programming.

负号运算符成员函数重载

//////////////////////////////////////////////////////// //////////////////////////////////////////////////////// //// /////////// //// 主题:负号运算符成员函数重载/////////// //// /////////// //// 作者:波斯顿律师/////////// //// //////////// //// 日期:02/10/2012 //////////// //// /////////// //////////////////////////////////////////////////////// //////////////////////////////////////////////////////// #include using namespace std; class Person { private: int iApple; public: Person(int iApple); void operator -(); void display(); }; int main() { Person XiaoSong(5); cout<<"\n调用operator -()负号运算符函数前"<iApple=iApple; } void Person::operator -() { iApple=-iApple; } void Person::display()

【例6.1】用成员函数重载运算符一

【例6.1】用成员函数重载运算符一 #include class RMB{ public: RMB(unsigned int d, unsigned int c); RMB operator+(RMB&); // 声明运算符函数,重载+,只有一个参数 RMB& operator++(); // 声明运算符函数,重载++,无参数 void display(){ cout << (yuan + jf / 100.0) << endl; } protected: unsigned int yuan; unsigned int jf; }; RMB::RMB(unsigned int d, unsigned int c) { yuan = d; jf = c; while(jf >=100){ yuan ++; jf -= 100; } }

RMB RMB::operator +(RMB& s) // 定义运算符函数 { unsigned int c = jf + s.jf; unsigned int d = yuan + s.yuan; RMB result(d,c); // 创建RMB对象result return result; } RMB& RMB::operator++() // 定义运算符函数 { jf ++; if(jf >= 100){ jf -= 100; yuan++; } return *this; // 返回当前对象 } void main() { RMB d1(1, 60); RMB d2(2, 50);

RMB d3(0, 0); d3 = d1 + d2; // 调用重载运算符函数operator +,使RMB类的两个对象可以相加 ++d3; // 调用重载运算符函数operator ++,使RMB类的对象d3可以自增 d3.display(); } 程序的运行结果为: 4.11

相关文档