正在加载……
专注、离线、切勿分心
const数据成员的初始化:
1、数据成员可以由const修饰,这样,一经初始化,该数据成员便具有“只读属性”,在程序中无法对其值修改;
2、在构造函数体内或复制构造函数体内初始化const数据成员是非法的(函数体内等价于赋值);
3、const数据成员只能通过成员初始化表进行初始化;
4、const修饰的变量只能调用const函数(普通变量也可以调用const函数;默认是不调用,除非没有非const函数)
#include <iostream>
using namespace std;
class point
{
        private:
                const int ix;
                const int iy;
        public:
                //const数据成员只能用初始化列表进行初始化
               point(int ix1=0,int iy1=0)
                :ix(ix1)
                ,iy(iy1)
                {
                        cout<<"构造函数:"<<endl;
                }
              point(const point &rhs)
                :ix(rhs.ix)
                ,iy(rhs.iy)
                {
                        cout<<"拷贝构造函数:const"<<endl;
                }
                void print()
                {
                        cout<<"("<<ix<<","<<iy<<")"<<endl;
                }
                void print()const
                {
                        cout<<"print const"<<endl;
                        cout<<"("<<ix<<","<<iy<<")"<<endl;
                }
};


void func(const point pt)   //换成const point &pt就不会调用复制构造函数
{
        pt.print();    //const变量,必须调用const成员函数
}
point fun2()
{
        cout<<"func2()"<<endl;
        point p2(5,6);
        p2.print();   //两个print函数都能调用,一般首选print
        return p2;
        //return调用复制构造函数
}
int main()
{
        point p1(3,4);  
        p1.print();

        func(p1);

        fun2();
        return 0;
}




#include<iostream>
using namespace std;
class point
{
        private:
                int _x;
                int _y;
        public:
                point(int x=0,int y=0):_x(x),_y(y)
                {
                        cout<<"point(int,int)"<<endl;
                }
                point(const point &rhs)
                {
                        _x = rhs._x;
                        _y = rhs._y;
                        cout<<"point(const point &)"<<endl;
                }
                void print()const
                {
                        cout<<"print()const";
                        cout<<"("<<_x<<","<<_y<<")"<<endl;
                }
                void print()
                {
                        cout<<"print()";
                        cout<<"("<<_x<<","<<_y<<")"<<endl;
                }
};
//func改为传引用,就不会再去调用拷贝构造函数
void func1(const point tmp)
{
        tmp.print();
}
void func2(point tmp1)
{
        tmp1.print();
}
int main()
{
        point pt1(1,2);
        const point pt2(3,4);
        func1(pt1);
        func1(pt2);  //奇怪,这里不发生拷贝构造函数,我把tmp改成tmp1就好了,定义函数这个也有关系?
        func2(pt1);
        //func2(pt2);  //error,func2函数只能调用非const的print
        return 0;
}
 //第二个函数改成tmp1




引用成员的初始化:
只能通过成员初始化表达式进行初始化
#include <iostream>
using namespace std;
class point
{
        private:
                int ix;
                int iy;
                int &ref1;
                double &ref2;
        public:
                point(int ix1,int iy1,double &d)  
                :ix(ix1)
                ,iy(iy1)
                ,ref1(ix)
//ref1(ix1),这样写就是引用的局部变量
                ,ref2(d)
                {
                        cout<<"构造函数:"<<endl;
                }
//ix和ref1都是同一个数,ref2和d是同一个数
                point(const point &rhs)
                :ix(rhs.ix)
                ,iy(rhs.iy)
                ,ref1(rhs.ref1)
                ,ref2(rhs.ref2)
                {
                        cout<<"拷贝构造函数:"<<endl;
                }
                void print()
                {
                        cout<<"("<<ix
                            <<","<<iy
                                <<","<<ref1
                                <<","<<ref2
                                <<")"<<endl;
                }
                void set_ix(int x)
                {
                        ix=x;
                }
};

int main()
{
        double d=5.0;
        point p1(3,4,d);
        p1.print();
        cout<<endl;

        point p2(p1);
        p2.print();
        cout<<endl;

        p1.set_ix(7);
        p1.print();
        p2.print();
        cout<<endl;

        d=9.9;
        p1.print();
        p2.print();
        return 0;
}



//构造函数引用了局部变量,直接显示了32767



类对象成员的初始化:
类数据成员也可以是另一个类的对象,构造函数初始化也只能用初始化成员列表

**********对复制构造函数来说,一旦给出了自己定义的形式,编译器便不会提供缺省的复制构造函数,因此,确保自定义的复制构造函数的有效性很重要**********
#include<iostream>
using namespace std;
class point
{
        private:
                int _x;
                int _y;
        public:
                point(int x=0,int y=0):_x(x),_y(y)
                {
                        cout<<"point(int,int)"<<endl;
                }
                point(const point &rhs):_x(rhs._x),_y(rhs._y)
                {
                        cout<<"point(const point &)"<<endl;
                }
                void print()
                {
                        cout<<"("<<_x<<","<<_y<<")";
                }
};
//line(const point pt1,const point pt2):_pt1(pt1),_pt2(pt2)
class line
{
        private:
                point _pt1;
                point _pt2;
        public:
                //line(const point pt1,const point pt2):_pt1(pt1),_pt2(pt2)
                line(const point &pt1,const point &pt2):_pt1(pt1),_pt2(pt2)
                {
                        cout<<"line(point,point)"<<endl;
                }
                void draw()
                {
                        _pt1.print();
                        cout<<"->";
                        _pt2.print();
                        cout<<endl;
                }
};
int main(void)
{
        point p1(1,2);
        point p2(8,9);
        line l1(p1,p2);
        l1.draw();
        return 0;
}
//line(const point &pt1,const point &pt2):_pt1(pt1),_pt2(pt2)




static数据成员的初始化:
C++允许使用static(静态存储)修饰数据成员,这样的成员在编译时就被创建并初始化的(与之相比,对象是在运行时被创建的),且其实例只有一个,被所有该类的对象共享
1、静态数据成员的初始化必须在类申明之外进行,且不再包含static关键字
                类型 类名::变量名 = 初始化表达式;                                 //普通变量
                类型 类名::对象名(构造参数);                                          //对象变量

#include <iostream>
using namespace std;
class computer
{
        private:
                float cprice;
                static float price;
        public:
                computer(float price1)
                :cprice(price1)
                {
                        cout<<"computer(float)"<<endl;
                        price+=cprice;
                }
                ~computer()
                {
                        cout<<"~computer()"<<endl;
                        price-=cprice;
                }
                void print()
                {
                        cout<<"总价格:"<<price<<endl;
                }
};
float computer::price=0.0;
int main()
{
        computer p1(2000);
        p1.print();

        computer p2(3000);
        p1.print();

        computer p3(4000);
        p3.print();

        p2.~computer();
        p3.print();
        return 0;
}


除了构造函数、复制构造函数和析构函数外,其他成员函数被用来提供特定的功能,一般来说,提供给外部访问的函数称为接口,访问权限为public,而一些不供外部访问,仅仅作为内部功能实现的函数,访问权限设为private



this指针
      1、一个类的所有对象共用成员函数代码段,不管有多少个对象,每个成员函数在内存中只有一个版本
      2、this指针是隐含在成员函数内的一种指针,称为指向本对象的指针,可以采用诸如“this->数据成员”的方式来存取类数据成员。
      3、类成员函数并不是一个对象对应一个单独的成员函数体,而是此类的所有对象共用这个成员函数体。 当程序被编译之后,此成员函数地址即已确定。而成员函数之所以能把属于此类的各个对象的数据区别开, 就是靠这个this指针。函数体内所有对类数据成员的访问, 都会被转化为this->数据成员的方式
      *4、this作用域是在类内部,当在类的非静态成员函数访问类的非静态成员的时候,编译器会自动将对象本身的地址作为一个隐含参数传递给函数
      5、类内部调用显示定义成私有的析构函数要通过this指针访问
private:
       ~student()
       {
           delete []name;
       }
public:
       void destroy()
       {
         
 this->~student();
       }
1。显式调用的时候,析构函数相当于的一个普通的成员函数

2。编译器隐式调用析构函数,如分配了对内存,显式调用析构的话引起重复释放堆内存的异常

3。把一个对象看作占用了部分栈内存,占用了部分堆内存(如果申请了的话),这样便于理解这个问题
      系统隐式调用析构函数的时候,会加入释放栈内存的动作(而堆内存则由用户手工的释放)
      用户显式调用析构函数的时候,只是单纯执行析构函数内的语句,不会释放栈内存,摧毁对象

#include <iostream>
#include<string.h>
using namespace std;
class computer
{
        private:
                char * brand;
                float price;
        public:
                computer(const char* brand1,float price1)
                :price(price1)
                {
                        cout<<"computer(const char*,float)"<<endl;
                        brand=new char[strlen(brand1)+1];
                        strcpy(brand,brand1);
                }
                computer & operator=(const computer & rhs)
                {
                         if(this==&rhs)
                         {
                               cout<<"operator=(const computer &)"<<endl;
                               return *this;
                         }               
                        delete []brand;
                        brand=new char[strlen(rhs.brand)+1];
                        strcpy(brand,rhs.brand);
                        price=rhs.price;
                        cout<<"operator=(const computer &)"<<endl;
                        return *this;
                }
                void print()
                {
                        cout<<"品牌:"<<this->brand<<endl;
                        cout<<"价格:"<<this->price<<endl;
                }
};
int main()
{
        computer com("DELL",7000);
        com.print();

        computer com1("IBM",8900);
        com1.print();

        com1=com1;
        com=com1;
        com.print();
        return 0;
}


#include <iostream>
using std::cout;
using std::endl;

class NullPointer
{
public:
        static void test1();
        void test2();
        void test3(int i);
        void test4();
private:
        static int _iStatic;
        int _iTest;
};
int NullPointer::_iStatic = 0;
void NullPointer::test1()
{
        cout << "static " << _iStatic << endl;
}
void NullPointer::test2()
{
        cout << "test2: very Cool! " << endl;
}
void NullPointer::test3(int i)
{
        cout << "test3: i = " << i << endl;
}
void NullPointer::test4()
{
        cout << "test4: _iTest = " << _iTest << endl;
}



int main(void)
{
        NullPointer * p = NULL;
        p->test1();
        p->test2();
        p->test3(1);
//前面三个不涉及通过this指针找对象类数据成员,所以即使传给this的值是空也没关系
        p->test4();      
//Error,传过去给this的地址为NULL,隐藏的this没法找到对应的数据
        return 0;
}



posted on 2018-04-12 08:43  正在加载……  阅读(239)  评论(0)    收藏  举报