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

合集下载

《CC++程序设计》(高起专)练习题

《CC++程序设计》(高起专)练习题

《C++程序设计》(高起专)练习题一一、单项选择题1.C++是一种()的程序设计语言。

A. 面向对象B. 即可面向过程,又可面向对象C. 面向过程D. 面向系统2.在下面有关析构函数特征的描述中,正确的是()。

A. 一个类中可以定义多个析构函数B. 析构函数名与类名完全相同C. 析构函数不能指定返回类型D. 析构函数可以有一个或多个参数3.下面对于友元函数描述正确的是()。

A. 友元函数的实现必须在类的内部定义B. 友元函数是类的成员函数C. 友元函数破坏了类的封装性和隐藏性D. 友元函数不能访问类的私有成员4.下面描述中,表达错误的是()。

A. 公有继承时基类中的public成员在派生类中仍是public的B. 公有继承时基类中的private成员在派生类中仍是private的C. 公有继承时基类中的protected成员在派生类中仍是protected的D. 保护继承时基类中的public成员在派生类中是private的5.所谓多态性是指()A. 不同的对象调用不同名称的函数B. 不同的对象调用相同名称的函数C. 一个对象调用不同名称的函数D. 一个对象调用不同名称的对象6.重载赋值操作符时,应声明为()函数。

A. 友元B. 虚C. 成员D. 多态7.下列对模板的声明错误的是()。

A. template <class T1,typename T2>B. template <class T1, T2>C. template < typename T>D. template <class T1,class T2,class T3>8.下列类中()不是输入流类istream的派生类。

A. ifstream C. iostream D. ofstream9.()不是构造函数的特征。

A. 构造函数的函数名与类名相同 B 构造函数可以重载C. 构造函数可以设置缺省参数 D构造函数必须指定类型说明10.下列语句中错误的是( )。

CPP复习题答案

CPP复习题答案

13. 派生类的对象对它的基类成员中 ( A ) 是可以采用对象·或者对象指针->的方 B. 公有继承的私有成员 D. 私有继承的公有成员 C ) 。
14. 关于纯虚函数和抽象类的描述中,错误的是( B. 抽象类是指具有纯虚函数的类。
A. 纯虚函数是一种特殊的虚函数,它没有具体的实现。 C. 一个基类中说明有纯虚函数,该基类的派生类一定不再是抽象类。 D. 抽象类只能作为基类来使用,其纯虚函数的实现由派生类给出。 15.下列说法错误的是( C )。 A.若语言只支持类而不支持多态,则不能称为面向对象的。 B.在运行时根据其类型确定调用哪个函数的能力叫多态性。 C.静态多态性也是在运行时根据其类型确定调用哪个函数。 D.C++中的静态多态性是通过函数重载进行实现的。 16. ( D )不是构造函数的特征 A. 构造函数的函数名与类名相同。 B. 构造函数可以重载。 C. 构造函数可以设置缺省参数。 D. 构造函数必须指定类型说明。 17.下列标识符中, A 不是 C++的关键字; A. cin B. private C. this D. operator 18.下列标识符中, A. cout A. cout 18.下列标识符中, A A 不是 C++的关键字; C. this C. this D. template D. sizeof 不是 C++的关键字; 不是 C++的关键字; C. this D. sizeof B. virtual B. public
A. 缩短程序代码,少占用内存空间 B. 既可以保证程序的可读性,又能提高程序的运行效率 C. 占用内存空间少,执行速度快 D. 使程序的结构比较清晰 3. 重载函数是( A ) A. 以函数参数来区分,而不用函数的返回值来区分不同的函数 B. 以函数的返回值来区分,而不用函数参数来区分不同的函数 C. 参数表完全相同而返回值类型不同的两个或多个同名函数 D. 参数表和返回值类型都必须是不同的两个或多个同名函数 4. 在 C++中,数据封装要解决的问题是( A. 数据的规范化 C. 避免数据丢失 5. 下列特性中,( B A.继承 之间的关系是( A. 组合关系 B.内联函数 C )。 B. 间接关系 C. 继承关系 D. 直接关系 D )。 B. 便于数据转换 D. 防止不同模块之间数据的非法访问 )不是面向对象的程序设计的特征。 C.多态性 D.封装

VC++6.0裏面20种C语言常见错误代码解释

VC++6.0裏面20种C语言常见错误代码解释

11、error C2509: 'OnTimer' : member function not declared in 'CHelloView'
成员函数“OnTimer”没有在“CHelloView”中声明。
12、error C2511: 'reset': overloaded member function 'void (int)' not found in 'B'
9、error C2146: syntax error : missing ';' before identifier 'dc'
句法错误:在“dc”前丢了“;”。
10、error C2196: case value '69' already used
值69已经用过。(一般出现在switch语句的case分支中)
重载的函数“void reset(int)”在类“B”中找不到。
13、error C2555: 'B::f1': overriding virtual function differs from 'A::f1' only by return type or calling convention
解决方法:
其一,包含正确路径的#include "stdafx.h";
其二,在*.cpp文件的Setting里面设置,C++选项中的分类 precompiled header,选择不包含头文件即可。
2、fatal error C1083: Cannot open include file: 'R…….h': No such file or directory

c友元函数和友元类用法详解

c友元函数和友元类用法详解

c友元函数和友元类用法详解C++中的友元函数和友元类是一种特殊的函数和类,它们可以访问类的私有成员变量和类的私有成员函数。

本文将详细介绍C++中友元函数和友元类的用法,以及在实际编程中应用友元函数和友元类所带来的优势。

首先,让我们来了解一下C++中什么是友元函数和友元类。

友元函数是一种特殊的函数,它允许外部函数访问类的私有成员变量和私有成员函数,而不需要对类进行任何修改。

友元函数还可以在类外定义,以便更加方便地使用它来访问类的私有成员变量和私有成员函数。

友元类是一种特殊的类,它允许一个类的私有成员函数访问另一个类的私有成员函数和私有成员变量,而不需要对类进行任何修改。

友元类也可以定义在类外,但其功能与友元函数不同,友元类可以访问另一个类的整个实例,而友元函数只能访问另一个类的私有成员变量和私有成员函数。

定义友元函数和友元类的用法其实非常简单,我们只需要在类的声明中使用关键字“friend”来指定友元的函数或类就可以了: class A {private:int a;public:void setA (int a);friend void foo (A& A); //友元函数};class B {private:int b;public:void setB (int b);friend class C; //友元类};以上的代码定义了两个类:A类和B类,其中A类定义了一个友元函数foo,而B类定义了一个友元类C。

定义完友元函数和友元类之后,就可以使用它们来访问类的私有成员变量和私有成员函数了。

在实际使用中,友元函数和友元类有着诸多的优势,比如可以更加方便的封装类的私有成员,以及更加方便的实现代码的重构。

首先,友元函数和友元类可以帮助我们更好地封装类的私有成员,使类的私有成员不能被外部类访问。

同时,可以使用友元函数和友元类来实现类的重构,这样可以更加方便地实现代码的复用,让程序更加简洁和易读。

VC6.0 error LNK2001 unresolved external symbol _main解决办法

VC6.0 error LNK2001 unresolved external symbol _main解决办法

VC6.0 error LNK2001: unresolved external symbol _main解决办法学习VC++时经常会遇到链接错误LNK2001,该错误非常讨厌,因为对于编程者来说,最好改的错误莫过于编译错误,而一般说来发生连接错误时,编译都已通过。

产生连接错误的原因非常多,尤其LNK2001错误,常常使人不明其所以然。

如果不深入地学习和理解VC++,要想改正连接错误LNK2001非常困难。

初学者在学习VC++的过程中,遇到的LNK2001错误的错误消息主要为:unresolved external symbol “symbol”(不确定的外部“符号”)。

如果连接程序不能在所有的库和目标文件内找到所引用的函数、变量或标签,将产生此错误消息。

一般来说,发生错误的原因有两个:一是所引用的函数、变量不存在、拼写不正确或者使用错误;其次可能使用了不同版本的连接库。

以下是可能产生LNK2001错误的原因:一.由于编码错误导致的LNK20011.不相匹配的程序代码或模块定义(.DEF)文件能导致LNK2001。

例如, 如果在C++源文件内声明了一变量“var1”,却试图在另一文件内以变量“VAR1”访问该变量,将发生该错误。

2.如果使用的内联函数是在.CPP文件内定义的,而不是在头文件内定义将导致LNK2001错误。

3.调用函数时如果所用的参数类型同函数声明时的类型不符将会产生LNK2001。

4.试图从基类的构造函数或析构函数中调用虚拟函数时将会导致LNK2001。

5.要注意函数和变量的可公用性,只有全局变量、函数是可公用的。

静态函数和静态变量具有相同的使用范围限制。

当试图从文件外部访问任何没有在该文件内声明的静态变量时将导致编译错误或LNK2001。

函数内声明的变量(局部变量) 只能在该函数的范围内使用。

C++ 的全局常量只有静态连接性能。

这不同于C,如果试图在C++的多个文件内使用全局变量也会产生LNK2001错误。

解决VC++6.0不能使用问题

解决VC++6.0不能使用问题

用VC++6.0时点“打开文件”时弹出“ox5003eaed”指令引用的“ox00000000”内存。

该内存不能为“read”2011-07-26 16:44问题:在Visual c + + 中使用键盘快捷键或从"文件"菜单中选择“打开”将产生以下错误:“0x5003eaed指令引用的"0x00000000"内存。

该内存不能为"read"。

要终止程序,请单击"确定"。

要调试程序,请单击"取消"。

” 的一个对话框。

当点击项目——>添加到项目——>文件时,将出现相同错误。

解决:FileTool.exe 是一个示例,用于替换“打开”和“添加到项目”菜单项在 Visual c + + 中使用开发工具 Studio 对象模型。

从 Microsoft 下载中心下载FileTool.exe :/download/vc60ent/s1/6.0/w9xnt4/en-us/filetool.exe自解压 FileTool.exe为FileTool文件夹待用。

为防止文件丢失,可将FileTool文件夹放在Visual c + + 6.0安装文件(:\Program Files\Microsoft Visual Studio)中。

一、首先安装外接程序:1. 运行 Visual c + + 6.0,文件--打开工作空间,打开刚才解压的filetool中的dsw工作空间文件编译,在DBUG文件夹中生成filetool.dll文件2.工具——>定制3.选择“附加项和宏文件”选项卡,单击浏览按钮并找到在第1 步中生成程序FileTool.dll 文件。

二、1. 工具——>定制——>键盘类别——>文件;命令——>FileOpen;编辑器——>主要;当前键——> CTRL + O ,单击“移去”:2. 类别——>工程;命令——>InsertFilesIntoProject。

new 能重载为友元函数

new 能重载为友元函数

new 能重载为友元函数1.引言1.1 概述在C++编程中,函数的重载和友元函数都是非常重要的概念。

函数的重载可以通过相同的函数名在同一作用域内定义多个函数,但参数类型或个数不同,从而根据不同的参数类型来选择调用相应的函数。

而友元函数是指在类外部定义的一个函数,它可以访问类中的私有成员和保护成员,从而实现对类的个别私有成员的特殊处理。

本文将重点讨论新的能够重载为友元函数的特性。

在传统的C++中,只有类的成员函数才能被声明为友元函数,而其他普通函数则不能。

然而,C++中的新特性引入了一种新的语法,使得普通函数也能够被声明为友元函数。

这一新特性在C++11标准中被引入,并在后续的C++标准中得到了进一步的完善和扩展。

通过将函数声明为友元函数,我们能够使这些函数能够访问类中的私有成员和保护成员,进而实现对类的特殊操作和处理。

接下来的章节中,我们将详细介绍函数的重载和友元函数的概念,以及它们在C++中的应用。

首先,我们将介绍重载函数的概念,包括其定义、使用方法和重载解析规则。

然后,我们将讨论友元函数的概念以及其与类的关系。

最后,我们将重点讨论新的能够重载为友元函数的特性,包括其优势和应用场景。

通过本文的学习,读者将能够更好地理解和应用函数的重载和友元函数的概念,进而提升自己的C++编程能力。

文章结构是指文章的组织方式和布局,它有助于读者更好地理解文章的内容和逻辑关系。

在本篇文章中,我们将按照以下结构来撰写和组织内容:1. 引言1.1 概述在这部分,我们将简单介绍本文的主题和内容,即"new 能重载为友元函数"。

1.2 文章结构这部分是我们所在的部分,我们将详细说明本文的结构和组织方式,并简要介绍每个部分的内容。

1.3 目的在这一部分,我们将说明写作本文的目的和意义,以及希望读者能够从本文中获得的收获和启发。

2. 正文2.1 重载函数的概念在这部分,我们将解释什么是函数重载,并介绍其基本概念、特点以及使用方式。

第四章 运算符重载

第四章 运算符重载

4.3重载运算符的规则
(1)C++只允许已有的部分运算符实施重载。 (2)不能重载的运算符有五个。 (3)重载不改变操作数的个数。 (4)重载不改变运算符的优先级。 (5)运算符重载函数不能带默认值参数。 (6)运算符重载函数必须与自定义类型的对象联 合使用,其参数至少有一个类对象或类对象引用。 (7)C++默认提供 = 和 & 运算符重载。
例4.1 通过成员函数实现复数的加法。 class Complex { private: double real; double imag; public: Complex(){real=0;imag=0;} Complex(double r,double i){real=r;imag=i;} Complex complex_add(Complex &c2); void display(); };
int main() {Complex c1(3,4),c2(5,-10),c3; c3=c1+c2; cout<<"c1=";c1.display(); cout<<"c2=";c2.display(); cout<<"c1+c2=";c3.display(); return 0; }
说明: (1)用运算符重载函数取代了例 4.1中的加法成 员函数,从外观上看函数体和函数返回值都是相 同的。 (2)在主函数中的表达式c3=c2+c1 取代了例4.1 中的c3=plex_add(c2) ,编译系统将表达 式c3=c1+c2 解释为 c1.operator + ( c2 ) 对象c1调用的重载函数operator + ,以c2为实参 计算两个复数之和。

C++重载函数运算符的两种定义方法(类中类外(友元))、重载操作运算符

C++重载函数运算符的两种定义方法(类中类外(友元))、重载操作运算符

C++重载函数运算符的两种定义⽅法(类中类外(友元))、重载操作运算符⼀、C++中重载运算符函数的⽅式:以重载‘-’号为例,⾃定义为乘法。

第⼀种是直接在类内声明定义:(返回值是本类的对象)#include <iostream>using namespace std;class test{public:test() {}test(int t1){item = t1;}test operator-(test &t2){this->item = this->item*t2.item;return *this;}void show(){cout << this->item;}private:int item;};int main(){test t1(10);test t2(20);test t3 = t1 - t2;t3.show();system("pause");return0;}第⼆种是在类中声明为友元函数,类外定义,返回值的是⼀个类的对象。

(⼀般为了能在类外直接调⽤成员⽽不⽤通过成员函数间接调⽤成员数据)#include <iostream>using namespace std;class test{public:test() {}test(int t1){item = t1;}void show(){cout << this->item;}friend test operator-(test &t1, test &t2);private:int item;};test operator-(test &t1, test &t2){test t;t.item = t1.item*t2.item;return t;}int main(){test t1(10);test t2(20);test t3 = t1 - t2;t3.show();system("pause");return0;}/*注意,如果新建⽴⼀个对象test t4(30);test t3=t1-t2-t4;此时运算符重载函数依然可以使⽤,但是,如果将运算符重载函数声明定义为返回的是⼀个对象的引⽤,t1-t2这⼀步骤完成后,做-t4这⼀步骤,此时会出现乱码,因为运算符重载函数返回的是⼀个对象的引⽤时,产⽣临时变量temp,但是会消失,此时对temp进⾏引⽤时已经不存在这个值了,所以出现乱码*/⼆、C++中操作符重载函数操作符重载函数中的重载左移操作符,其函数定义不建议写在类中,因为cout<<test,左边是ofstream对象,如果放到类中定义,其调⽤是test.operator<<,变成test<<cout右移操作符⼤同⼩异#include <iostream>using namespace std;class test{public:test(){}test(int t){temp=t;}void show(){cout<<temp;}friend ostream& operator<<(ostream &os,test &t1); //为了能直接调⽤类的数据成员,声明为友元函数private:int temp;};ostream& operator<<(ostream &os,test &t1) //<<操作符重载函数只写在全局,{os<<t1.temp<<endl;return os;}int main(){test t1(10);cout<<t1;system("pause");return0;}注!操作符重载函数返回引⽤⽬的是为了能够连续赋值。

C++运算符重载三种形式(成员函数,友元函数,普通函数)详解

C++运算符重载三种形式(成员函数,友元函数,普通函数)详解

C++运算符重载三种形式(成员函数,友元函数,普通函数)详解三种重载⽅式⾸先,介绍三种重载⽅式:1//作为成员函数重载(常见)2class Person{3 Private:4string name;5int age;6public:7 Person(const char* name, int age):name(name),age(age){}8bool operator<(const Person& b);910 };11bool Person::operator<(const Person& b)12 {13//作为成员函数时,*this即为左操作数a14 ...15 }1//作为友元函数重载2class Person{3private:4string name;5int age;6public:7 Person(const char* name, int age):name(name),age(age){}8 friend bool operator<(const Person& a,const Person& b);910 };11bool operator<(const Person& a,const Person& b)12 {13 ...14 }1//作为普通函数重载(不推荐)2class Person{3public://注意,重载运算符为普通函数时,使⽤到的类成员必须为public4string name;5int age;6public:7 Person(const char* name, int age):name(name),age(age){}89 };10bool operator<(const Person& a,const Person& b)11 {12 ...13 }作为成员函数重载先介绍第⼀种:bool Person::operator<(const Person& b),bool是函数返回类型,Person::只是指定了成员函数所属类名。

VC6.0常见问题

VC6.0常见问题

1.VC6.0常见编译错误提示(1)error C2001: newline in constant编号:C2001直译:在常量中出现了换行。

错误分析:①字符串常量、字符常量中是否有换行。

②在这句语句中,某个字符串常量的尾部是否漏掉了双引号。

③在这语句中,某个字符创常量中是否出现了双引号字符“"”,但是没有使用转义符“\"”。

④在这句语句中,某个字符常量的尾部是否漏掉了单引号。

⑤是否在某句语句的尾部,或语句的中间误输入了一个单引号或双引号。

(2)error C2015: too many characters in constant编号:C2015直译:字符常量中的字符太多了。

错误分析:单引号表示字符型常量。

一般的,单引号中必须有且只能有一个字符(使用转义符时,转义符所表示的字符当作一个字符看待),如果单引号中的字符数多于4个,就会引发这个错误。

另外,如果语句中某个字符常量缺少右边的单引号,也会引发这个错误,例如:if (x == 'x || x == 'y') , … -值得注意的是,如果单引号中的字符数是2-4个,编译不报错,输出结果是这几个字母的ASC码作为一个整数(int,4B)整体看待的数字。

(3)error C2137: empty character constant编号:C2137直译:空的字符定义。

错误分析:原因是连用了两个单引号,而中间没有任何字符,这是不允许的。

(4)error C2018: unknown character '0x##'编号:C2018直译:未知字符‘0x##’。

错误分析:0x##是字符ASC码的16进制表示法。

这里说的未知字符,通常是指全角符号、字母、数字,或者直接输入了汉字。

如果全角字符和汉字用双引号包含起来,则成为字符串常量的一部分,是不会引发这个错误的。

(5)error C2041: illegal digit '#' for base '8'编号:C2141直译:在八进制中出现了非法的数字‘#’(这个数字#通常是8或者9)。

VC6.0错误指令及解决方法

VC6.0错误指令及解决方法

1 error C2065: 'xxx' : undeclared identifier 102012136xxx标识符没定义。

标识符可能是变量名,函数名等等。

注意检查拼写,注意大小写。

注意小写字母l和数字1的区别。

检查变量的定义和使用是否一致。

变量定义语句:在函数最前面,以变量类型开始,以分号分隔的几个变量名,如int a, b; 注意一个变量定义语句只能写一个变量类型。

2 error C2146: syntax error : missing ';' before identifier 'xxx'语句末尾缺少分号,一般是错误定位所在行的上一行。

3 error LNK2001: unresolved external symbol _main没有main函数。

检查拼写,看是否把main写成了mian。

4 fatal error C1021: invalid preprocessor command 'includ'预处理指令拼写错误。

5 fatal error C1083: Cannot open include file: 'stio.h': No such file or directory包含文件名写错了。

文件名中间不能有空格。

6 error C2001: newline in constant检查是否漏了双引号,双引号是否配对,是否把双引号"写成了单引号'。

7 程序运行弹出非法操作的对话框。

检查是否有scanf漏掉&符号的问题。

8 编译时没错,链接有错:error LNK2005: _main already defined in a.objfatal error LNK1169: one or more multiply defined symbols found一般是在一个程序里面有多个源文件都包含main函数。

VC++操作及常见问题解决方法

VC++操作及常见问题解决方法

VC++操作及常见问题解决方法一VC++有关操作方法:1整理代码:选上所有较乱的代码,同时按下Alt加F8键即可.2图形界面与命令提示符界面数据的复制方法:在图形界面按Ctrl+C,在命令提示符界面点击右键->粘贴即可.3VC编程时不显示提示信息(类的成员和参数列表)解决:1).菜单-->工具(Tools)-->选项(Options)-->编辑器(Editor)-->语句完成选项(Statement completion options)--->勾选自动列出成员(Auto list members)。

2).关闭工程-->把工程下的.ncb(VC++ Intellisense Database)文件删除-->再重新打开工程即可。

3).安装Visual AssistX插件(下载地址/detail/wentasy/4010401)4切换工程:工具栏空白处点右键->选取组件(取消初使选取的是编译微型条)->通过VC编译器的下拉列表可切换工程.链接库文件:工程->设置->连接->对象/库模块(移到最后)->输入相应库文件->确定5增加消息处理器:1)右键ClassView的类名->选Add Windows Message Handler->选WM_...->选Add Handler->选EditExisting;2)点VC++的菜单查看->选建立类向导->选工程->选类名->选消息->选Add Function->选Edit Code.3)先双击类名在头文件的DECLARE_MESSAGE_MAP()前的注释宏间加入消息响应原型声明,然后双击构造函数名在源文件中的BEGIN_MESSAGE_MAPHE和END_MESSAGE_MAP间的注释宏间加入消息响应函数的宏,最后在源文件中实现.6.windowsAPI程序引用C++类(如error C2065: 'CString' : undeclared identifier错误)的方法:包含<Afx.h>头文件(不要<windows.h>);定义预处理器(工程->设置->C/C++->预处理器定义:_AFXDLL);选择多线程(工程->设置->C/C++->CodeGeneration->Use run-time library->Multithread DLL).7.删除消息处理函数及相关信息:右键函数名->Delete->是.8.使用多线程的C run-time library(用MFC时也要使用多线程): 编译多线程程序时提示error C2065: '_beginthread' : undeclared identifier 解决方法是:debug状态:settings-> C/C++-> Project Options中加入/MDdrelease状态:settings-> C/C++-> Project Options中加入/MD.9.链接库文件的方法:1) 使用#pragma comment(lib,"MyDll.lib")语句;2) 在工程的Setting->Link页的Object/Moduls栏填入MyDll.lib既可。

C++学习之路—运算符重载(二)运算符重载作为类的成员函数和友元函数

C++学习之路—运算符重载(二)运算符重载作为类的成员函数和友元函数

C++学习之路—运算符重载(⼆)运算符重载作为类的成员函数和友元函数对运算符重载的函数有两种处理⽅式:(1)把运算符重载的函数作为类的成员函数;(2)运算符重载的函数不是类的成员函数,在类中把它声明为友元函数。

1 把运算符重载函数作为类的成员函数例1:为了便于说明问题,将重载函数的定义重写如下:1: Complex Complex :: operator + ( Complex& c2 )2: {3: Complex c ;4: c.real = real + c2.real ;5: c.imag = imag + c2.imag ;6:return c ;7: }有⼈可能会提出这样的疑问:“+”是双⽬运算符,为什么重载函数只有⼀个参数呢?实际上,运算符重载函数应当有两个参数,但是,由于重载函数是Complex类中的成员函数,因此有⼀个参数是隐含的,运算符函数是⽤this指针隐式的访问类对象的成员。

可以看到operator+访问了两个对象中的成员,⼀个是this指针指向的对象中的成员,⼀个是形参对象中的成员。

2 把运算符重载函数作为类的友元函数运算符重载函数除了可以作为类的成员函数外,还可以是⾮成员函数。

在有关的类中把它声明为友元函数,即友元运算符重载函数。

例2:将运算符+重载为适⽤于复数加法,重载函数不作为成员函数,⽽放在类外,作为Complex类的友元函数。

1:class Complex2: {3:public:4: ...5:friend Complex operator + ( Complex& c1 , Complex& c2 ) ; //重载函数作为友元函数6:private:7:double real ;8:double imag ;9: };10:11: Complex operator + ( Complex& c1 , Complex& c2 ) //定义运算符+重载函数12: {13: Complex c ;14: c.real = c1.real + c2.real ;15: c.imag = c1.imag + c2.imag ;16:return c ;17: }这个程序和把运算符重载函数作为类的成员函数相⽐,只做了⼀处改动,就是将运算符重载函数作为类外的普通函数,并在Complex类中声明它为友元函数。

c++访问私有private成员变量的常用方法

c++访问私有private成员变量的常用方法

c++访问私有private成员变量的常⽤⽅法⽬录下⾯是其它⽹友的补充访问C++类对象中私有成员变量的⽅法类的对象不能直接访问类声明的私有成员变量,否则破坏了信息隐藏的⽬的。

在C++中,为了防⽌某些数据成员或成员函数从外部被直接访问,可以将它们声明为private,这样编译器会阻⽌任何来⾃外部⾮友元的直接访问。

私有成员变量的常⽤访问⽅法如下:(1)通过公共函数为私有成员赋值#include <iostream>using namespace std;class Test{private:int x, y;public:void setX(int a){x=a;}void setY(int b){y=b;}void print(void){cout<<"x="<<x<<'\t'<<"y="<<y<<endl;}} ;int main(){Test p1;p1.setX(1);p1.setY(9);p1.print( );return 0;}(2)利⽤指针访问私有数据成员#include <iostream>using namespace std;class Test{private:int x,y;public:void setX(int a){x=a;}void setY(int b){y=b;}void getXY(int *px, int *py){*px=x; //提取x,y值*py=y;}};int main(){Test p1;p1.setX(1);p1.setY(9);int a,b;p1.getXY(&a,&b); //将 a=x, b=ycout<<a<<'\t'<<b<<endl;return 0;}(3)利⽤函数访问私有数据成员#include <iostream>using namespace std;class Test{private:int x,y;public:void setX(int a){x=a;}void setY(int b){y=b;}int getX(void){return x; //返回x值}int getY(void){return y; //返回y值}};int main(){Test p1;p1.setX(1);p1.setY(9);int a,b;a=p1.getX( );b=p1.getY();cout<<a<<'\t'<<b<<endl;return 0;}(4)利⽤引⽤访问私有数据成员#include <iostream>using namespace std;class Test{private:int x,y;public:void setX(int a){x=a;}void setY(int b){y=b;}void getXY(int &px, int &py) //引⽤ {px=x; //提取x,y值py=y;}};int main(){Test p1,p2;p1.setX(1);p1.setY(9);int a,b;p1.getXY(a, b); //将 a=x, b=ycout<<a<<'\t'<<b<<endl;return 0;}下⾯是其它⽹友的补充访问C++类对象中私有成员变量的⽅法原则上,C++类中私有变量不允许在类之外的其他任何地⽅访问,⼀般来说功能完善的类都会提供get,set⽅法来操作类属性值,但如果没有get、set⽅法都没有提供,⽐如使⽤的是第三⽅提供的.o(或者动态库)来进⾏开发的,并且实际应⽤中我们确确实实需要改变其中某个对象的⼀个私有参数,有没有什么办法呢?我们知道,⼀个进程有程序段和数据段,如果我们知道了对象的数据空间,那么得到该对象的成员变量值也就很简单了,⽽实际上,对象数据段的⾸地址其实就是对象地址,以例⼦说明:class A{public:int i;bool setJ(int _j){j = _j;};int getJ() const {return j;};private:int j;};int main(){A a;printf("a's address is %u.n",&a); // 打印对象a的地址printf("a.i's address is %u.n",(&(a.i))); // 打印对象a的成员变量i的地址}执⾏上⾯程序,可以看到结果,两个值时⼀样的,也就是说明对象地址就是第⼀个成员变量的地址。

VC++ 6.0提示“Cannot add new member”解决方案

VC++ 6.0提示“Cannot add new member”解决方案

VC++ 6.0提示“Cannot add new member”解决方案本人原创,欢迎免费下载问题描述:在使用VC++6.0双击按钮控件准备添加响应函数时,提示“Cannot add new member”。

原因:VC++6.0的工作区包含多个工程,准备添加响应函数的按钮所属工程不是当前活动工程。

解决方法:将准备编辑的按钮所属工程设置为活动工程。

设置方法,在类视图工程名称上右键->设为活动工程。

终极解决方法(纯手工敲代码):1、在BEGIN_MESSAGE_MAP()下加入ON_BN_CLICKED(IDC_BUTTON1, OnButton1)前者为控件ID后者为函数名;2、在同文件的类的protected:// Generated message map functions//{{AFX_MSG(CSelecteDlg)下面添加:afx_msg void OnButton1();3、在源文件中加入:void 类::OnButton1(){。

}-------------------------------。

下面是其他同类问题的其他解决方案。

---------------------关闭工程-------删除.ncb .aps \debug \release 删掉或许要是有.clw也要删掉呵呵--重新打开工程---回到资源的编辑页面-------------ctrl+W 出现选择对话框------选择resouse.h-----------确定---ok 就可以双击这个按钮编辑消息函数了--------------------有些文件只只读的,,选取所有工程文件去掉只读属性,,再不行,,就重新生成工程文件。

-------------------把.ncb、.clw、.aps、.dsw文件删掉,然后重.dsp重新打开,打开后Ctrl+W重新生成工程文件,就应该可以了。

------------------*****方案一:*****你的工程是不是从低版本VC转到了高版本VC,比如VC6.0转到了VC8.0,我碰到过这种问题,解决方法就是,重新建Dialog,把控件复制到新Dialog,再拷贝相应的响应函数和变量。

C++重载(主要介绍使用友元函数重载)

C++重载(主要介绍使用友元函数重载)

C++重载(主要介绍使⽤友元函数重载)重载限制多数C++运算符都可以⽤下⾯的⽅式重载。

重载的运算符不必是成员函数,但必须⾄少有⼀个操作数是⽤户⾃定义的类型。

下⾯详细介绍C++对⽤户定义的运算符重载的限制。

1 重载后的运算符必须⾄少有⼀个操作数是⽤户⾃定义的类型,这将防⽌⽤户为标准类型重载运算符。

因此,不能将减法运算符(-)重载为double值的和,⽽不是它们的差。

虽然这种限制将对创造性有所影响,但可以确保程序正常运⾏。

2 使⽤运算符时不能违反运算符原来的句法规则。

例如,不能将求模运算符(%)重载成使⽤⼀个操作数。

同样,不能修改运算符的优先级。

因此,如果将加号运算符重载成将两个类相加,则新的运算符与原来的加号具有相同的优先级。

3 不能创建新的运算符。

例如,不能定义operator**()函数来表⽰求幂。

4 不能重载下⾯的运算符sizeof:sizeof运算符.:成员运算符.*:成员指针运算符:: :作⽤域解析运算符?::条件运算符typeid:⼀个RTTI运算符const_cast:强制类型转换运算符dynamic_cast:强制类型转换运算符reinterpret_cast:强制类型转换运算符static_cast:强制类型转换运算符然⽽,下表中的所有运算符都可以被重载5 下表中的⼤多数运算符都可以通过成员或⾮成员函数进⾏重载,但下⾯的运算符值能通过成员函数进⾏重载=:赋值运算符():函数调⽤运算符[]:下标运算符->:通过指针访问类成员的运算符可重载的运算符除了这些正式限制之外,还应在重载运算符时遵循⼀些限制。

例如,不要将*运算符重载成交换两个对象的数据成员。

友元C++控制对类对象私有部分的访问。

通常,公有类⽅法提供唯⼀的访问途径,这种限制太严格,以⾄于不适合特定的编程问题。

在这种情况下,C++提供了另外⼀种形式的访问权限:友元。

友元有3种:友元函数友元类友元成员函数通过让函数成为类的友元,可以赋予该函数与类的成员函数相同的访问权限。

C++之类成员的访问权限详解(一)

C++之类成员的访问权限详解(一)

C++之类成员的访问权限详解(⼀)概念解析众所周知,⾯向对象编程语⾔的特征之⼀就是封装,不同编程语⾔对于封装提供的实现有所不同,但原理⼤体上是相同的。

C++提供了三种不同程度的访问权限来实现,主要是通过public 、private 、protected 三个关键字实现的。

下⾯我们来详细分析⼀下这三个关键字的具体作⽤和区别。

这三个关键字主要⽤来控制类或者结构体成员变量和成员函数的访问权限,称为成员访问限定符,分别代表公有的、受保护的、私有的,它们所表达的封装程度不同,在使⽤时需要特别注意。

访问权限限定符的使⽤⼜跟类本⾝的性质有关,即继承对访问权限的使⽤有⼀定的影响,本⽂主要探讨⽆继承情况下的访问。

public限定符被public 限定符所修饰的成员变量和函数可以被类的函数、⼦类的函数、友元函数,也可以由类的对象来访问,即可以使⽤成员运算符来访问。

这⾥的友元函数,可以是该类的友元函数,也可以是该类的友元类的成员函数。

使⽤形式如下:12345678class temp{ public: int a; //修饰成员变量 temp() //修饰成员函数,这⾥修饰构造函数 {//初始化类对象成员}}protected 限定符protected 限定符修饰的成员变量和成员函数可以被该类的成员函数访问,但是不能被类对象所访问,即不能通过类对象的成员运算符来访问。

另外,这些成员可以被⼦类的函数和友元函数访问,相⽐public 成员 少了⼀个可以使⽤类对象直接访问的特性。

具体使⽤与public 类似,这⾥不再贴出代码。

private 限定符被private 限定符修饰的成员变量只能被该类的⽅法和友元函数访问,⼦类函数⽆法访问,在这三个限定符中封装程度是最⾼的,⼀般来说,应该尽可能将类的成员变量声明为private ⽽不是其他,减少成员变量的暴露,只提供getter 和settter ⽅法给外界访问,这样能提⾼类的安全性。

友元函数重载插入运算符

友元函数重载插入运算符

友元函数重载插入运算符:让C++输出更灵
活便捷!
友元函数是什么?友元函数是指在一个类中,可以访问另一个类中的私有成员的函数,它是被允许访问私有成员的“好朋友”。

而重载插入运算符就是利用友元函数来重载“<<”运算符,使得C++中的输出更加灵活便捷。

接下来,我们来看一个例子:
include <iostream>
using namespace std;
class MyClass{
private:
int num;
public:
MyClass(int n){
num = n;
}
friend ostream& operator<<(ostream& os, const MyClass& obj){
os << obj.num;
return os;
}
};
int main(){
MyClass obj(123);
cout << obj << endl;
return 0;
}
在上面这个例子中,我们定义了一个MyClass类,其中包含一个私有的成员变量num。

然后,我们在该类中将重载插入运算符“<<”作为友元函数,使其可以访问MyClass类中的私有成员变量。

最后在主函数中创建了一个MyClass对象obj,并将其输出至屏幕上。

结果为123,符合预期。

如此一来,我们就可以轻松地使用C++输出我们自定义的类了。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

VC6.0中重载操作符友元函数无法访问类的私有成员的解决办法
VC6.0中重载操作符友元函数无法访问类的私有成员的解决办法:
在C++中,操作符(运算符)可以被重载以改写其实际操作。

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

在Visual C++中定义一般的函数为友元函数通常是没有问题的。

然而对某些重载操作符的函数,即使我们将它们定义为类的友元函数,VC的编译器仍然会显示出错信息,认为这些友元函数无权访问类的私有成员。

我认为这应该是VC6.0编译器与标准C++不兼容的地方。

以下代码就是个例子:
// 头文件“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;
};
// 实现文件“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中编译的时候就会出现以下的编
译错误:
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 <iostream>
using namespace std;
// 以下3行代码为新加入
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<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;
};
第三种方法:是对I/O名空间的使用实行明确声明,也就是说在头文件”Sample.h”中直接写:#include<iostream>
using std::ostream;
using std::istream
….
取代“using namespace std;”
注意:在这个例子里我们在实现文件“Sample.cpp”中包含“using namespace std;”这句话,否则在实现中就不能使用“cout”, “cin”, “<< “, “>>”和endl 这些关键字和符号。

修改后的完整代码如下:
// Sample.h
#include<iostream>
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”<<endl;
in >> s.x ;
return in;
}
ostream &operator<<(ostream &out, const Sample s) {
cout << s.x << endl;
return out;
}。

相关文档
最新文档