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;
}
|
引用成员的初始化:
只能通过成员初始化表达式进行初始化
|
#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;
}
|
浙公网安备 33010602011771号