有空间不一定有对象。
有对象一定有空间。
class Empty
{
};
int main()
{ //看不见构造函数,是因为,只要程序运行,系统会调用默认构造函数,创建对象
Empty e; //占位符,有对象,一定要有空间
cout<<sizeof(e)<<endl;
Empty *p = &e; //如果e没空间,指向哪?
}
1.创建对象
2.初始化对象中的属性。
3.类型转换
class Int
{
public :
Int(x = 0):value(x){}
}
int main()
{
Int ix (12);
int a = 200;
ix = a; //赋值给ix的时候,会创建调动构造函数一个无名对象,将a传给ix(完成了类型转换。)
}
new(&c1) Comlex(200,300)
,可以让c1再构建一次。class Complex
{
double Real;
double Image;
public:
Complex(){}
Complex(double r,double i)//函数重载
{
Real = r;
Image = i;
}
fun(Complex cx)
{}
}
int main()
{
Complex c1; //调用的Complex()默认构造函数
Complex c2(1.1,2.2);//调用的是Complex(double r,double i)
Complex c3();//一定要写数据,负责会被认为是函数的声明
complex c4{};//可以,列表的初始化方案
fun(Complex(2,3));//构造函数一定要获取某个空间,在某个空间构造对象。
}
Complex c3();
/一定要写数据,负责会被认为是函数的声明
4. 构造函数可以在类中定义,也可以在类外定义
5. 如果类说明中没有给出构造函数,C++编译器会自动生成一个缺省构造函数
complex(){}
只要我们自己定义一个构造函数,系统就不会自动生成缺省构造函数,
如果构造函数不带参数或者带参数没有缺省值(如下图),就会被认为缺省构造函数。
关键字:sizeof(),编译期确定大小。
构造函数一定要获取某个空间,在某个空间构造对象。
class Complex
{
private:
double Real;
double Image;
public:
Complex(){}//Complex(Complex *const this)
}
Complex c1; Complex(&c1)
struct 内默认为public
class 内默认为private
struct str
{
int a;
char b; //可以通过str s; s.a =1,s.b = "s";进行初始化
}
class Com
{
private:
int real; //private: int real;int image;
public : //public: Com(int r = 0,int i = 0)
int image // Com c3{3,4} Com c2 = {2}; 均可初始化,从右往左
}
int main()
{
Com c1 = {1}; //错误,
Com c2 = {2}; //错误 必须是成员属性均为公有,才可以初始化,
//系统会自动提供一个有两个形参的构造函数。
// Com(int ,int);
Com c3{3,4} ;
}
初始化和设计顺序必须相同。
class Complex
{
private:
double Real;
double Image;
public:
Complex():real(0),image(0)//成员初始化列表
{}
Complex(double r,double i):real(r),image(i)
{
Real = r;
Image = i;
}
}
可能出现的问题:
class Complex
{
private:
int real;
int image;
public:
Complex(int x) :image(x), real(image) {}//read(x),image(real)可以
void print()
{
cout << "real:" << real << "image:" << image << endl;
}
};
int main()
{
Complex c1(10);
c1.print();
}
列表初始化的顺序最好和属性定义的顺序相同,否则如图。
类中定义了多个构造函数,:向现实靠拢,每个人的出身不同,所带的属性也就不同
int &Real() ,相当于返回this指针指向对象的别名
{
return real;
}
【对象的生存期满了就会自动调用。】
用构造函数创建对象后,程序负责跟踪对象,当对象使用结束,系统就会调用析构函数,完成对对象的清理。
注意:
1.析构函数不可重载,无可见参数
2.析构函数如果自己没有实现,系统会默认生成一个。
语法:~函数名()
Complex c1(1,1);
int main()
{
cout<<"begin main"<<endl;
Complex c1(10);
cout<<"end main:"<<endl;
return 0;
}
Complex c3(3,3);
不论全局函数在哪,在进入主函数之前都会定义好,
4.块内对象:进入块中调用构造函数创建对象,从块中出来,析构对象。
//只在块中有效
int main()
{
cout<<"begin main"<<endl;
Complex c1(1,1);
cout<<"begin 块:"<<endl;
{
Complex c2(2,2);
} //这个位置块内对象析构
cout<<"end 块"<<endl;
cout<<"end main"<<endl;
return 0;
}
int main()
{
Complex cs(1,1);
//
cs.~Complex(); //主动调动。
return 0;
}
5.动态创建的对象, 使用new创建对象,delete释放对象
int main()
{
int n = 5;
// Complex* xp = new Complex[n]{{1,2},{},{4,5},{6,7}};//1.申请堆空间2.创建对象(调用的是有参的构造函数)
// {}调用的是无参构造函数
Complex* xp = new Complex{};
// xp -> print();
for(int i = 0;i<n;i++)
{
xp[i].Print(); //申请了一组对象
}
// delete xp; //1.析构对象,将内存还给申请空间,2.将申请的空间还给堆
delete []xp;
xp = nullptr;
}
有空间不一定有对象,必须要调用构造函数创建对象。
所以,不能调用对象的方法。
有对象才可以对空间进行操作。
如下:
int main()
{
Complex *xp = (Complex*)malloc(sizeof(Complex));//只申请空间,没有兑现
//调动构造函数再new指定的xp申请的空间中构建对象
new (xp) Complex{2,3};//定位new,构建对象。这样
xp->print(); // xp才可以访问对象的方法。
xp->~Complex();//主动析构对象。
free(xp);
xp = NULL
}
所以malloc + 定位new实现了 new 的功能。
当类中的成员属性设置为私有的时候,可以通过成员方法访问或修改成员属性。
如:
class Complex
{
private:
int num;
int age;
public:
int set_num(int n)
{
num = n;
}
// int set_age(const Complex *const this ,int a)
int set_age(int a) const //常方法 但是导致无法对age进行赋值
{
age = a;
}
int get_num() const //在获取数据的时候加const,只读不写
{
return num;
}
int get_age() const
{
return age;
}
}
int main()
{
Complex cc;
cc.set_num(10); //通过成员方法。。。
const Complex ss; //常对象 ,约束的是指向能力,一般用于获取数据
ss.set_age(20); //只能访问常方法
cc.set_age(10);//也可以。能力缩小 导致无法写入数据
//在获取数据的时候加const,只读不写
ss.get_age();
cc.get_num();
}
(主要就是this指针的可访问性权限,指向的能力)
如下:
class Complex
{
private:
int num;
int age;
public:
int set_num(int n)
{
num = n;
}
//int print(const Complex *const this,int n)
int print(int n)const
{
//
this->set_num(n)//错误,因为set_num(n) 相当于set_num(this,n),print的this 放入sert_num,能力被扩大
}
// int set_age(const Complex *const this ,int a)
int get_num() const //在获取数据的时候加const,只读不写
{
this->print();// print(this) 常方法可以调用常方法
return num;
}
int get_age()
{
this->print(); //普通方法也可以调用常方法,因为可以this指针传给print的this,能力被缩小。
return age;
}
}