Chinaunix首页 | 论坛 | 博客
  • 博客访问: 239226
  • 博文数量: 91
  • 博客积分: 2010
  • 博客等级: 大尉
  • 技术积分: 955
  • 用 户 组: 普通用户
  • 注册时间: 2007-08-12 09:38
文章分类

全部博文(91)

文章存档

2017年(1)

2011年(1)

2008年(15)

2007年(74)

我的朋友

分类: LINUX

2008-01-03 22:32:25

                      Class
类默认是私有,而结构体默认是公有
class fault is private, truct fault is public

 对象仅只包含类,构造器和成员函数属于类
object include data only, contructor and member_function blong to class

illustrate: there ere three files class.h class.c++ main1.c++
如果一个类中定义了多个构造函数,最好定义一个无参构造器,因为类继承时,调用的是无参构造器
list class.h
class tdate
{
private:
int month;
int day;
int year;
public:
//you must define a contructor which didn't include parameters
//when have one or more contructor which have one or more parameters
tdate();
tdate(int t_month, int t_day, int t_year)
{
month=t_month;
day=t_day;
year=t_year;
}
//tdate(const tdate &obj)
//{}
void display();
};

list class.c++:

#include
#include "class.h"
void tdate::display()
{
cout<<"the current month== "< }

list main1.c++:

#include
#include "class.h"//need class tdate
int main()
{
tdate t1(12,30,2007);
tdate t2=tdate(12,31,2007);//impractical but allowed
tdate t3=t2;//invoking the copy contructor
//the method is can not running normal
//tdate t4(t1)
//it can running normal
tdate t4(t2);
t1.display();
t2.display();
t3.display();
t4.display();
return 0;
}

now running it

[zhang@localhost c++]$ g++ -c class.c++
In file included from /usr/include/c++/3.2.2/backward/iostream.h:31,
                 from class.c++:1:
/usr/include/c++/3.2.2/backward/backward_warning.h:32:2: warning: #warning This
file includes at least one deprecated or antiquated header. Please consider using one of the 32 headers found in section 17.4.1.2 of the C++ standard. Examples
include substituting the header for the header for C++ includes, or instead of the deprecated header . To disable this warning
use -Wno-deprecated.
[zhang@localhost c++]$ g++ -o main1 main1.c++ class.o
In file included from /usr/include/c++/3.2.2/backward/iostream.h:31,
                 from main1.c++:1:
/usr/include/c++/3.2.2/backward/backward_warning.h:32:2: warning: #warning This
file includes at least one deprecated or antiquated header. Please consider using one of the 32 headers found in section 17.4.1.2 of the C++ standard. Examples
include substituting the header for the header for C++ includes, or instead of the deprecated header . To disable this warning
use -Wno-deprecated.
[zhang@localhost c++]$ ./main1
the current month== 12 day== 30 year== 2007
the current month== 12 day== 31 year== 2007
the current month== 12 day== 31 year== 2007

示例程序第一种对象构造方法虽然不实用,但他演示了临时对象(temporary object)的构造方法,这是因为等号右边生成了一个临时对象tdate,再赋给对象t1, 赋值完后就自动消失了,临时对象很麻烦,有可能为导致缺陷,所以我们应尽量避免产生临时对象

一定要记住,所有的参数都有缺省值时,类不能再声明一个无参构造器,如下面的代码将无法编译
public:
tdate();
tdate(int t_month=0, int t_day=0, int t_year=0)
因为所有的参数都有缺省时,就相当于一个无参构造器了

调试类方法和函数相同
debug class method same as debug function

当用delete时,就会调用析构函数
it will invoking the 析构 function when use delete

指针类对象
pointer class object

创建动态类对象
tdate *object_p;//create object
p=new tdate;
通常用下面的方法
the above sentences equal to : tdate *object_p=new tdate;//create dynamic object
使用类对象
now can use the pointer object:
such as: object_p->display();//use object
删除类对象(此时会调用析构函数)
delete object_p;//delete object which invoking ~tdate()
在main1.c++中添加如下的语句就可以了
append follow lines on list main1.c++:
//create a dynamic object
tdate *object_p;
object_p=new tdate(1,1,2008);
//the above code equal to the follow line
//tdate *object_p=new tdate;
object_p->display();
delete object_p;
//it is over

在类中使用指针,和将该程序放在文件class.h中
use pointer in class and put it in class.h
class anyclass
{
private:
tdate *p;
public:
anyclass()
{p=new tdate(2,2,2008)}
~anyclass()
{//trace ~anyclass()'
s invoking
cout<<"delete the dynamic";
delete p;}
void display()
{
p->display();
}
};

在main1.c++中添加如下的行
append follow lines in main1.c++:
anyclass p;
p.display();

复制构造器
copy structor
here is a illustrate: list copy.c++
#include <iostream.h>
class test
{
private:
int x,y;
public:
test(int k1,int k2)
{x=k1;
 y=k2;
}
test()
{}
test(const test &p)
{x=p.x*2;
y=p.y+2;
}
void display();
//the follow is a friend function
friend void disp(test &p);
};
void test::display()
{
cout<<x<<" "<<y<<endl;
}
void disp(test &p)
{cout<<"this is a friend invoking";
cout<<p.x<<" "<<p.y<<endl;
}
int main()
{
test p1,p2(4,5);
p2.display();
//call overload operator function operator=()
p1=p2;//calls operator=()
test px(p2);//invoking the copystructor function and it only in defined
                                                                                
p1.display();
cout<<"this is the second invoking";
//p1(p2);this is wrong;
px.display();
test pk=p2;//invoking the copystructor function and it only in defined
cout<<"this is the third invoking";
//p1(p2);this is wrong;
pk.display();
disp(px);
pk.display();
disp(px);
return 0;
}

the output result:
4 5
4 5
this is the second invoking8 7
this is the third invoking8 7
this is a friend invoking8 7

当然我们可以定义一个重载操作符去验证p1=p2
also we can define a overload function to verify it(p1=p2)
you can applend follow lines in class test of copy.c++
void operator =(const test ©)
{
cout<<"call the overload function operator =()"<<endl;
x=copy.x;
y=copy.y;
}

从以上的例子可以知道,只有在类对象定义时赋给一个类对象才会调用拷贝构造函数,否则就会调用重载操作符函数
当然,你也可以调用这默认的重载操作符
of course, you can call the default operator=() function
以下还是operator=();但调用的是指针
list prompt.c++
#include <iostream.h>
#include <string.h>
class prompt
{
private:
char *p;
public:
prompt()
{}
prompt(const char *s)
{
p=new char[strlen(s)+1];
strcpy(p,s);
}
void operator=(const prompt ©);
~prompt()
{
cout<<"the delete function"<<endl;
delete []p;
}
void display();
};
void prompt::operator=(const prompt ©)
{
if(this==&copy)//avoid copying self to self
return;
delete []p;//delete old data
p=new char[strlen(copy.p)+1];
strcpy(p, copy.p);
}
void prompt::display()
{
cout<<p<<endl;
}
int main()
{
prompt pro1,pro2("hello are you good");
pro1=pro2;
pro2.display();
pro1.display();
return 0;
}
重载操作符可以调用私有变量

初始化列表
类对象只能用初始列表的方法来初始化
initialize list
class inilist
{
private:
prompt pros;// a class object data member
int x;
int y;
public:
//inilist(int c):pros("I am ok"),x(1){y=c}
//define out of class
inilist(int c);
void display();
};
void inilist::display()
{
pros.display();
cout<<x<<endl;
}
inilist::inilist(int c):pros("I am ok"),x(1){y=c}

 再在main()里添加如下语句
 inilist inil1(8);
 再运行程序,结果为
 I am ok
1
8
the delete function

各种类对象
类对象作为函数参数
class c_funclass
{
private:
int x;
public:
c_funclass(int y):x(y)
{}
void display(c_function &dis)
{
dis.print();
}
void print();
};
void c_funclass::print()
{
cout<<x<<endl;
}
 类对象作为函数参数时,最好用引用或指针,这样可以节省很多的时间,如果不想修改指针,可以声明为const
 对象函数结果
 返回值为类对象(利用class prompt)
 prompt any_function()
 {
 prompt pro("are you ok");
 return pro;//return the copy of object
}
在程序的其它地方用下列语句赋值
prompt pro1=any_function();
首先用函数any_function 构造了一个对象,再将对象返回,生成一个临时对象,用返回的临时对象构造pro1,最终要删除临时对象,这里调用了三个构造器和二个对象备份,如果用指针,只需构造一个对象。
实现代码如下:
prompt* any_function()
{
return new pro("are you ok");
}
prompt pro1=any_function();
当然,对象pro1必须显示的删除。
delete pro1;
而如果是返回对象的引用,效率会更高
prompt& any_function()
{
return today;
}
对象today必须在其它的地方生成
prompt &pro1=any_function();
使用指针的好处是,内存地址比大多数对象小。
在多次出现的复杂程序中,效率是主要的考虑因素

动态类对象数组
dynamical object array

prompt *p;
p=new prompt[6];
for(int i=0;i<6;i++)
p[i].display();
delete []p;
默认会为变量初始化为0

对象指针的数组
test *p[2];
所有指针类型为test *,但他并不生成test object, 如果想生成对象,在for循环中使用new
for(int i=0;i<2;i++)
{
p[i]=new test;
}
必须要主要,由于数组包含对象的指针,你要负责用new构造每个对象。调用每个对象的display()成员函数如下
for(int i=0;i<2;i++)
{
p[i]->display();
}

最后删除数组中的所有对象,由于数组包含对象的指针而不是对象本身,c++并不自动删除对象,也不调用任何类析构器,应显示地调用delete,以删除每个对象,如下for循环所示:
for(int i=0;i<2;i++)
{
delete p[i];
}
 
 对象数组作为数据成员
class xy
{
private:
test uu[10];
public:
.........
};

下一部分(class base2)是类继承
the next(class base2) is class inherit


以下是完整的详细源代码

list class.h

#include
class tdate
{
private:
int month;
int day;
int year;
public:
//you must define a contructor which didn't include parameters
//when have one or more contructor which have one or more parameters
tdate();
tdate(int t_month, int t_day, int t_year)
{
month=t_month;
day=t_day;
year=t_year;
}
//tdate(const tdate &obj)
//{}
void display();
};
//use pointer in class and use object as pointer
class anyclass

class anyclass
{
private:
tdate *p;
public:
anyclass()
{p=new tdate(2,2,2008);}
void display()
{
p->display();
}
~anyclass()
{//trace the delete function
cout<<"invoking the delete function"<delete p;}
};
class test
{
private:
int x,y;
public:
test(int k1,int k2);
test()
{}
test(const test &p);
void operator =(const test ©);//calls operator=() member function
                                                                               
void display();
//the follow is a friend function
friend void disp(test &p);
};
class prompt
{
private:
char *p1;
public:
prompt()
{
}
prompt(const char *s)
{
p1=new char[strlen(s)+1];
strcpy(p1,s);
}
//void operator =(const prompt ©);
~prompt()
{
cout<<"the delete function"<delete []p1;
}
void display();
};
class inilist
{
private:
prompt pros;// a class object data member
int x;
int y;
public:
//initialize the class object and it the unique method
//inilist(int c):pros("I am ok"),x(1){y=c;}
inilist(int c);
//class object as function
void add(inilist &xy);
void display();
};


list class.c++


#include
#include "class.h"
#include //need strlen() strcpy()
void tdate::display()
{
cout<<"the current month== "<}
void test::display()
{
cout<}
void disp(test &p)
{cout<<"this is a friend invoking";
cout<}
test::test(const test &p)
{x=p.x*2;
y=p.y+2;
}
void test::operator =(const test ©)
{
cout<<"overload operator function"<x=copy.x;
y=copy.y;
}
test::test(int k1,int k2)
{x=k1;
 y=k2;
}
//void prompt::operator =(const prompt ©)
//{
//if(this==©)//avoid copying self to self
//return;
//delete []p1;//delete old data
//p1=new char[strlen(copy.p1)+1];
//strcpy(p1, copy.p1);
//}
void prompt::display()
{
cout<}
void inilist::display()
{
pros.display();
cout<cout<}
inilist::inilist(int c):pros("I am ok"),x(1){y=c;}
void inilist::add(inilist &xy)
{
x=xy.x+3;
}


list main1.c++



#include
#include "class.h"//need class tdate, anyclass,test
//have pointer copy structor
#include
void prompt1()
{
prompt pro1,pro2("hello are you good");
pro1=pro2;
pro2.display();
pro1.display();
}
int main()
{void tdate_test();//declaration tdate_test
tdate_test();//invoking tdate_test()
anyclass any;
any.display();
void copy_structor();//declaration copy_structor
//invoking copy_structor function
copy_structor();
//invoking the prompt();
prompt1();
//create a inilist object
inilist inil1(8);

inil1.display();
inil1.add(inil1);
inil1.display();
return 0;
}
void tdate_test()
{
tdate t1(12,30,2007);
tdate t2=tdate(12,31,2007);//impractical but allowed
tdate t3=t2;//invoking the copy contructor
//the method is can not running normal
//tdate t4(t1)
//the follow can running normal
tdate t4(t2);
t1.display();
t2.display();
t3.display();
t4.display();
//create a dynamic object
tdate *object_p;
object_p=new tdate(1,1,2008);
//the above code equal to the follow line
//tdate *object_p=new tdate;
object_p->display();
delete object_p;
}
void copy_structor()
{
test p1,p2(4,5);
p2.display();
//calls overloaded operator=() member function
p1=p2;//don't invoking the copystructor function
test px(p2);//invoking the copystructor function and it only in defined
                                                                               
p1.display();
cout<<"this is the second invoking";
//p1(p2);this is wrong;
px.display();
test pk=p2;//invoking the copystructor function and it only in defined
cout<<"this is the third invoking";
//p1(p2);this is wrong;
pk.display();
disp(px);
//define a dynamic array
test *p;
p=new test[2];
for(int i=0;i<2;i++)
{
p[i].display();
cout<<"dynamic array"<}
delete[] p;
//define a dynamic pointer array
test *pp[2];
for(int i=0;i<2;i++)
pp[i]=new test;
for(int i=0;i<2;i++)
pp[i]->display();
//delete dynamic array
for(int i=0;i<2;i++)
delete pp[i];
}




阅读(1593) | 评论(0) | 转发(0) |
0

上一篇:linux下的c++(base 1)

下一篇:c++ (base 3)

给主人留下些什么吧!~~