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==©)//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]; }
|