类的初始探究

----------------------- 析构函数---------------------------------------

  析构函数名也应与类名相同,只是在函数名前面加一个位取反符~,例如~stud( ),以区别于

构造函数。它不能带任何参数,也没有返回值(包括void类型)。只能有一个析构函数,不能重

载。如果用户没有编写析构函数,编译系统会自动生成一个缺省的析构函数即使自定义了析构

函数,编译器也总是会为我们合成一个析构函数,并且如果自定义了析构函数,编译器在执行时

会先调用自定义的析构函数再调用合成的析构函数,它也不进行任何操作。所以许多简单的类

中没有用显式的析构函数。

----------------------- 显示定义复制构造函数-----------------------

#include <iostream>
#include <cstring>
using namespace std;
class Computer
{
    private:
        char *brand;
        float price;
    public:
        Computer(const char *sz,float pce)
        {
            brand=new char[strlen(sz)+1];
            strcpy(brand,sz);
            price=pce;
        }
        Computer(const Computer &cp)   //自定义复制构造函数 
        {
            brand=new char[strlen(cp.brand)+1]; //重新为brand开辟与cp.brand同等大小的动态内存 
            strcpy(brand,cp.brand); //字符串复制 
            price=cp.price;
        }
        ~Computer()
        {
            delete[] brand;
            cout<<"清理现场"<<endl;
        }
        void print()
        {
            cout<<"品牌:"<<brand<<endl;
            cout<<"价格:"<<price<<endl;
        }
};
int main()
{
    Computer comp1("Dell",7000);
    comp1.print();
    
    Computer comp2(comp1); //调用复制构造函数声明Computer类对象comp2,并用comp1为其初始化
// 相当于 Computer comp2=comp1;
comp2.print(); return 0; }

---------------- const数据成员的初始化-----------------------------------------------

const关键字修饰的成员变量只能在初始化列表中进行初始化

#include <iostream>
#include <cstring>
using namespace std;
class Point
{
    private:
        const int xPos;
        const int yPos;
     public:
// 初始化表的顺序取决于成员声明的顺序,若yPos的声明在前,xPos的声明在后,
// 则以下初始化语句应先初始化 yPos(y),后初始化 xPos(x);
Point (
int x,int y):xPos(x),yPos(y) // const 数据成员只能在初始化表中初始化 { } //const 数据成员只能在初始化表中进行初始化,对复制构造函数来说同样如此 Point(const Point &cpt):xPos(cpt.xPos),yPos(cpt.yPos) { } void print() { cout<<"("<<xPos<<","<<yPos<<")"<<endl; } }; int main() { Point pt1(3,4); pt1.print(); Point pt2(pt1); //相当于Point pt2=pt1; pt2.print(); return 0; }

---------------- 引用数据成员的初始化-----------------------------------------------

对于引用类型的数据成员,同样只能通过成员初始化表达式进行初始化

#include <iostream>
#include <cstring>
using namespace std;
class Point
{
    private:
        int xPos;
        int yPos;
        int& ref1;
        double& ref2;
    public:
        Point(int x,int y,double & z):ref1(xPos),ref2(z)    //引用成员的初始化同样要放在初始化表中
        {
            xPos=x;
            yPos=y;
        }
        //复制构造函数与此一致:引用成员的初始化同样要放在初始化表中
        Point(const Point& pt):ref1(pt.ref1),ref2(pt.ref2)
        {
            xPos=pt.xPos;
            yPos=pt.yPos;
         }
        void print()
        {
            cout<<"xPos: "<<xPos<<", yPos: "<<yPos<<endl;
            cout<<"ref1:  "<<ref1<<", ref2:  "<<ref2<<endl;
        }
        void SetX(int x)
        {
            xPos=x;
        }
};
int main()
{
    double outInt=5.0;
    Point pt1(3,4,outInt);
    pt1.print();
    Point pt2(pt1);     // 相当于  Point pt2=pt1;
    pt2.print();
    cout<<"改变pt1中的x后"<<endl;
    pt1.SetX(7);
    pt1.print();
    pt2.print();
    outInt=6;
    cout<<"outInt变化后:"<<endl;
    pt1.print();
    pt2.print();
    return 0;
}

---------------- 类对象成员的初始化-----------------------------------------------

#include <iostream>
#include <cstring>
using namespace std;
class point                        //点类的定义
{
    private:
        int xPos;
        int yPos;
    public:
        point(int x=0,int y=0)        //带缺省调用的构造函数
        {
            cout<<"点的构造函数被执行"<<endl;
            xPos=x;
            yPos=y;
        }
        point(const point& pt)        //复制构造函数
        {
            cout<<"点的复制构造函数被执行"<<endl;
            xPos=pt.xPos;
            yPos=pt.yPos;
        }
        void print()
        {
            cout<<"( "<<xPos<<", "<<yPos<<")";
        }
};
class line                            //line类的定义
{
    private:
        point pt1;                        //point类对象作为line类成员,此处若写成point pt1(3,4),错
        point pt2;
    public:
        line(int x1,int y1,int x2,int y2):pt1(x1,y1),pt2(x2,y2) //line对象的有参构造函数
        {
            cout<<"线的构造函数被执行"<<endl;
        }
        line(const line& ll):pt1(ll.pt1),pt2(ll.pt2)        //line对象的复制构造函数
        {
            cout<<"线的复制构造函数被执行"<<endl;
        }
        void draw()
        {
            pt1.print();
            cout<<"  to  ";
            pt2.print();
            cout<<endl;
        }
};
int main()
{
    line l1(1,2,3,4);        //调用有参构造函数
    l1.draw();
    line l2(l1);            //调用复制构造函数
    l2.draw();
    return 0;
}

 -----------------------------静态成员函数的用法-----------------------------------------------------

(1) 静态成员函数既可以定义为 inline 的,如“ static void print_total()”,又可以定义在函数

外部,如“ void computer::print(computer& com) ”,在类定义之外时,不能用 static 。

(2) 静态成员函数不与特定的对象联系,基本的调用格式如下所示:

类名::静态成员函数名(参数表);

静态成员函数也可以由类的对象来访问,如:

comp1.print_total(); 和 comp2.print_total();
#include <iostream>
#include <cstring>
using namespace std;
class computer
{
    private:
        char* name;
        float price;
        static float total_price;                //静态数据成员
    public:
        computer(const char* chr,const float p)    //构造函数,模拟买电脑操作
        {
            name=new char[strlen(chr)+1];
            strcpy(name,chr);
            price=p;
            total_price+=p;
        }
        ~computer()                                //析构函数,模拟退掉电脑的操作
        {
            delete[] name;
            total_price-=price;            
        }
        static void print_total()                //静态成员函数,原则上只能访问静态数据成员
        {
            cout<<"总价:"<<total_price<<endl;
        }
        static void print(computer& com);        //静态成员函数print()原型,如果要访问某具体对象,必须传递参数
};
void computer::print(computer& com)                //静态成员函数print()实现
{
    cout<<"名称: "<<com.name<<endl;
    cout<<"价格: "<<com.price<<endl;
}
float computer::total_price=0;           //静态成员的初始化
int main()
{
    computer comp1("IBM",7000);            //声明类对象comp1,初始化,买入
    computer::print(comp1);                //类名加作用域限定符访问statci成员函数,传递参数comp1
    computer::print_total();            //类名加作用域限定符访问statci成员函数
    computer comp2("ASUS",4999);        //声明类对象comp2,初始化,买入
    computer::print(comp2);                //类名加作用域限定符访问statci成员函数,传递参数comp2
    computer::print_total();
    comp2.~computer();                    //析构函数调用,退还电脑
    computer::print_total();
    return 0;
}

  -----------------------------const成员函数及const对象的用法---------------------------------------

  const成员函数表示该成员函数只能读类数据成员,而不能修改类成员数据。如果const成员

函数试图以任何方式改变类的数据成员或调用另一个非const成员函数,编译器将给出错误信息。

  类对象也可以声明为const对象,一般来说,能作用与const对象的成员函数除了构造函数

和析构函数外,便只有const成员函数了,因为const对象只能被创建、撤销以及只读访问,改

写是不允许的。

#include <iostream>
using namespace std;
class point                    //类定义
{
    int x;                    //默认private型成员变量x和y
    int y;
public:
    point(int xp=0,int yp=0)//构造函数
    {
        x=xp;
        y=yp;
    }
    void SetX(int xp)        //非const成员函数SetX,设置x
    {
        x=xp;
    }
    void SetY(int yp)        //非const成员函数SetY,设置y
    {
        y=yp;
    }
    void print() const        //const成员函数print,不能修改x和y
    {
        cout<<"x: "<<x<<" ,y: "<<y<<endl;
    }
};
//或者
// void print() const;
// void point::print() const
//{
//  cout<<"x:"<<x<<" ,y"<<y<<endl;
int main() { point pt(3,4); //声明一个普通类变量pt pt.SetX(5); //使用pt可调用非const成员函数 pt.SetY(6); pt.print(); //pt也可调用const成员函数 const point ptC(1,2); //声明一个const对象(类变量) //ptC.SetX(8); //错误,ptC是const对象,只能调用const成员函数 //ptC.SetY(9); //错误,ptC是const对象,只能调用const成员函数 ptC.print(); //正确,const对象只能调用const成员函数 return 0; }

  

posted @ 2013-05-10 14:34  sky&moon  阅读(135)  评论(0编辑  收藏  举报