复杂形式的类与对象 | 总字数: 2.7k | 阅读时长: 11分钟 | 浏览量: |
摘要 介绍了C++中复杂形式的类与对象,包括对象数组、对象指针、this指针、拷贝构造函数、向函数传递对象的方法,以及常类型(常引用、常对象、常成员函数、常数据成员)的使用和注意事项。
目录 [TOC]
对象数组与对象指针 对象数组 所谓对象数组就是每一数组元素都是对象的数组。
定义一个一维数组的格式如下: 类名 数组名[下标表达式];
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 #include <iostream> class exam { public : void set_x (int n) { x=n; } int get_x () { return x; } private : int x; }; main (){ exam ob[4 ]; int i; for (i=0 ;i<4 ;i++) ob[i].set_x (i); for (i=0 ;i<4 ;i++) cout<<ob[i].get_x ()<<′ ′; cout<<endl; return 0 ; }
对象指针 用指针访问单个对象成员 声明对象指针的一般语法形式为: 类名* 对象指针名
当用指向对象的指针来访问对象成员时,要用->
操作符。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 #include <iostream> class exe { public : void set_a (int a) { x=a; } void show_a () { cout<<x<<endl; } private : int x; }; main (){ exe ob,*p; ob.set_a (2 ); ob.show_a (); p=&ob; p->show_a (); return 0 ; }
用对象指针访问对象数组 将上面程序改写为:
1 2 3 4 5 6 7 8 9 10 11 int main () { exe ob[2 ],*p; ob[0 ].set_a (10 ); ob[1 ].set_a (20 ); p=ob; p->show_a (); p++; p->show_a (); return 0 ; }
this指针 在 C++ 中,this 指针是一个特殊的指针,它指向当前对象的实例。
在 C++ 中,每一个对象都能通过 this 指针来访问自己的地址。
this 是一个隐藏的指针,可以在类的成员函数中使用,它可以用来指向调用对象。
当一个对象的成员函数被调用时,编译器会隐式地传递该对象的地址作为 this 指针。
友元函数没有 this 指针,因为友元不是类的成员,只有成员函数才有 this 指针。
下面的实例有助于更好地理解 this 指针的概念:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 #include <iostream> class MyClass { private : int value; public : void setValue (int value) { this ->value = value; } void printValue () { std::cout << "Value: " << this ->value << std::endl; } }; int main () { MyClass obj; obj.setValue (42 ); obj.printValue (); return 0 ; }
显示this指针的值:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 #include <iostream> class A { public : A (int x1){ x=x1; } void disp () { cout << "\nthis=" << this << "when x=" << this ->x; } private : int x; }; int main () { A a (1 ) ,b (2 ) ,c (3 ) ; a.disp (); b.disp (); c.disp (); return 0 ; }
拷贝构造函数 拷贝构造函数 是一种特殊的构造函数,它在创建对象时,是使用同一类中之前创建的对象来初始化新创建的对象。拷贝构造函数通常用于:
通过使用另一个同类型的对象来初始化新创建的对象。
复制对象把它作为参数传递给函数。
复制对象,并从函数返回这个对象。
如果在类中没有定义拷贝构造函数,编译器会自行定义一个。如果类带有指针变量,并有动态内存分配,则它必须有一个拷贝构造函数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 #include <iostream> using namespace std;class Coord { public : Coord (int a,int b) { x=a; y=b; cout<<"Using normal constructor\n" ; } void print () { cout<<x<<" " <<y<<endl; } private : int x,y; }; int main () { Coord p1 (30 ,40 ) ; Coord p2 (p1) ; Coord p3=p1; p1. print (); p2. print (); p3. print (); return 0 ; }
调用拷贝构造函数的三种情况:
用类的一个对象初始化另一个对象时
1 2 3 4 Coord p2 (p1) ; Coord p3=p1;
形参是对象,实现形参和实参的结合
1 2 3 4 5 6 7 8 9 10 11 fun1 (Coord p) { p.print (); } int main () { Coord p1 (10 ,20 ) ; fun1 (p1); 结合时,调用拷贝构造函数 return 0 ; }
返回值是对象时
1 2 3 4 5 6 7 8 9 10 11 12 Coord fun2 () { Coord p1 (10 ,30 ) ; return p1; } main (){ Coord p2; p2=fun2 (); 调用拷贝构造函数 return 0 ; }
向函数传递对象 使用对象作为函数参数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 #include <iostream> using namespace std;class aClass { public : aClass (int n) { i=n; } void set (int n) { i=n; } int get ( ) { return i; } private : int i; }; void sqr (aClass ob) { ob.set (ob.get ()*ob.get ()); cout<<"copy of obj has i value of " ; cout<<ob.get ()<<"\n" ; } int main () { aClass obj (10 ) ; sqr (obj); cout<<"But, obj.i is unchanged in main:" ; cout<<obj.get ( ); return 0 ; }
使用对象指针作为函数参数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 #include <iostream> using namespace std;class aClass { public : aClass (int n) { i=n; } void set (int n) { i=n; } int get () { return i;} private : int i; }; void sqr (aClass *ob) { ob->set (ob->get () * ob->get ()); cout<<"Copy of obj has i value of " ; cout<<ob->get ()<<"\n" ; } int main () { aClass obj (10 ) ; sqr (&obj); cout<<"Now, obj.i in main() has been changed :" ; cout<<obj.get () <<"\n" ; return 0 ; }
使用对象引用作为函数参数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 #include <iostream.h> class aClass { public : aClass (int n) { i=n; } void set (int n) { i=n; } int get () { return i;} private : int i; }; void sqr (aClass& ob) { ob.set (ob.get () * ob.get ()); cout<<"Copy of obj has i value of " ; cout<<ob.get ()<<"\n" ; } int main () { aClass obj (10 ) ; sqr (obj); cout<<"Now, obj.i in main() has been changed :" ; cout<<obj.get () <<"\n" ; return 0 ; }
常类型 常引用 用const声明的引用就是常引用。
常引用所引用的对象不能被更改,经常见到的是常引用作为函数的形参,这样不会发生对实参的误修改。
常引用的声明形式为:const 类型说明符 &引用名
。
常引用作为函数形参的例子如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 #include "iostream" using namespace std;void fun (const double &d) ;int main () { double d = 3.14 ; fun (d); return 0 ; } void fun (const double &d) { double i = 6.66 ; cout << "d = " << d << endl; }
常对象 常对象是指数据成员在它的生存期内不会被改变。
定义常对象时必须对其进行初始化,并且不能改变其数据成员的值。
常对象的声明形式为:类名 const 对象名 或者 const 类名 对象名。
常对象的例子如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 class A { public : A (int i, int j){ i = x; j = y; } private : int x; int y; }; int main () { A const a (1 , 2 ) ; return 0 ; }
如果程序中出现对常对象的数据成员试图进行修改的语句,编译器会报错。一般修改对象的数据成员有两种途径,一种是通过对象名访问公有数据成员并修改其值,而常对象的数据成员是不能被修改的;另一种是类的成员函数修改数据成员的值,而常对象不能调用普通的成员函数。可是这样的话,常对象就只剩数据,没有对外的接口了,这就需要为常对象专门定义的常成员函数了。
类的常成员函数 类中用const声明的成员函数就是常成员函数,常成员函数的声明形式为:类型说明符 函数名(参数表) const;
常成员函数需要注意的几点:
常成员函数在声明和实现时都要带const关键字;
常成员函数不能修改对象的数据成员,也不能访问类中没有用const声明的非常成员函数;
常对象只能调用它的常成员函数,不能调用其他的普通成员函数;
const关键字可以被用于参与对重载函数的区分。比如,如果有两个这样声明的函数:void fun(); void fun() const;,则它们是重载函数。
常成员函数实例如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 class R { public : R (int i1, int i2){ R1 = i1; R2 = i2; } void Print () ; void Print () const ; private : int R1; int R2; }; void R::Print () { cout << "R1 = " << R1 << " , R2 = " << R2 << endl; } void R::Print () const { cout << "R1 = " << R1 << " , R2 = " << R2 << endl; } int main () { R r (5 , 4 ) ; r.Print (); R const rr (20 , 45 ) ; rr.Print (); return 0 ; }
常数据成员 类的数据成员也可以是常量和常引用,用const声明的数据成员就是常数据成员。
在任何函数中都不能对常数据成员赋值。构造函数对常数据成员初始化,只能通过初始化列表
。常数据成员实例如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 class B { public : B (int i); void Print () ; const int &r; private : const int a; static const int b; }; const int B::b = 330 ;B::B (int i): a (i), r (a){ cout << "B的对象的构造函数\n" ; } void B::Print () { cout << "a = " << a << " , b = " << b << " , r = " << r << endl; } int main () { B b1 (50 ) ; B b2 (550 ) ; b1. Print (); b2. Print (); return 0 ; }