C++ 1.2 this指针 构造函数

一、this 指针(节省空间,时间换空间)

对象可以根据属性来区分,为了降低空间复杂度,可以让同类型对象共享一份成员函数。

1.编译器针对设计的类型分三步编译:

(1)识别和记录类中的属性(名称、类型、访问限定)

(2)识别和记录类中函数的声明

例如:对于以下代码,调用函数funa()时其内部调用func(),func()在funa()后面定义,故显示无法识别func(),除非先声明 void func(); 才可。

#include<iostream>
using namespace std;
void funa()
{
	func();
}
void func()
{
}
int main()
{
	funa();//会显示无法编译通过
	return 0;
}

而如果是类成员函数则可以编译通过。正是由于编译器对设计的类分三步编译(主要由于第二步):

#include<iostream>
using namespace std;
class Fun
{
public:
	void funa()
	//void funa(Fun* const this)
	{
		func();//this->func();
	}
	void func()
	//void func(Fun* const this)
	{
	}
};
int main()
{
	Fun c1;
	c1.funa();//funa(&c1);
	return 0;
}

(3)改写在类中定义函数的参数列表(形参列表加入this指针,类名*const this)和函数体(出现成员变量的地方改为this->属性),改写对象调用成员函数的形式(c1.CountTotal变为CountTotal(&c1))。

下面为C++ 1.1中代码编译的效果(改写在注释中):

#include<iostream>
using namespace std;
const int LEN{ 20 };
class CGoods
{
private: 
	char Name[LEN];
	int Amount;
	float Price;
	float Total_Price;
public:
	void RegisterGoods(const char*, int, float);
	//void RegisterGoods(CGoods* const this,const char*,int,float);
	void CountTotal();
	//void CountTotal(CGoods* const this);
	const char* Get_name();
	//const char* Get_name(CGoods* const this);
	int Get_amount(); //同理
	float Get_price(); //
	float Get_totalprice() //float Get_totalprice(CGoods* const this)
	{
		return Total_Price;
		//return this->Total_Price;
	}
};
//返回值类型 类名::函数名(参数列表){}
void CGoods::RegisterGoods(const char* name, int amount, float price)
//void CGoods::RegisterGoods(CGoods* const this,const char* name, int amount, float price)
{
	strcpy_s(Name, LEN, name);
	//strcpy_s(this->Name,LEN,name);
	Amount = amount;
	//this->Amount=amount;
	Price = price;
	//this->Price=price;
}
void CGoods::CountTotal()
//void CGoods::CountTotal(CGood* const this)
{
	Total_Price = Price * Amount;
	//this->Total_Price=this->Price * this->Amount;
}
const char* CGoods::Get_name() { return Name; }
int CGoods::Get_amount() { return Amount; }
float CGoods::Get_price() { return Price; }
float CGoods::Get_totalprice() { return Total_Price; }
int main()
{
	CGoods c1;
	c1.RegisterGoods("C++", 15, 29);
	//RegisterGoods(&c1,"C++", 15, 29);
	c1.CountTotal();
	//CountTotal(&c1);
	return 0;
}

 2.仅有类成员函数有this指针(this指针实质为成员函数的一个形参,函数调用时产生this指针,函数调用结束this指针消失),全局函数也无this指针。

二、构造函数

1.数据成员多为私有,要对其进行初始化,必须用一个公有函数来进行,该函数为构造函数(类成员函数,有this指针)

构造函数作用:(1)创建对象;(2)初始化对象属性;(3)进行类型转换

构造函数特征:(1)函数名与类名同;(2)无返回类型(!=void),构造函数返回构造的对象;(3)构造函数在对象生存期内只被调用一次!(4)构造函数可以重载;(5)类中若未定义构造函数,则会自定义一个缺省的(无参、只可构造对象,不可初始化),无参构造函数=各参数均有缺省值=缺省构造函数

#include<iostream>
using namespace std;
class Complex
{
private:
	int Real;
	int Image;
public:
	Complex()
	//Complex(Complex* const this)
	{
		Real = 0;//若不给值~为随机值
		Image = 0;
	}
	Complex(int x, int y)
	{
		Real = x;
		Image = y;
	}
	void Print()
	{
		cout << "Real:" << Real << "  Image:" << Image << endl;
	}
};
int main()
{
	Complex c1;//调用无参构造函数,构造对象,不初始化
	Complex c2(12, 23);//调用两参构造函数构造对象并初始化
	c1.Print();
	c2.Print();
	return 0;
}

2.空间只能申请。有空间不一定有对象,有对象一定有空间。

#include<iostream>
using namespace std;
class Empty
{
};
int main()
{
	Empty a1;//由于分配空间,故需要占位符1个字节
	cout << sizeof(a1) << endl;
}

3.虽然说构造函数在对象生存期内只被调用一次,但可以打破规则使用定位new实现2次调用(不要轻易进行二次调用)

Complex c1; //c1调用构造函数初始化c1.Real=0,c1.Image=0

new(&c1) Complex(23,34); //定位new,再次调用构造函数重新对c1的属性初始化

4.缺省构造函数只能有一个!Complex(){} 和Complex(int x=0,int y=0){} 均代表缺省构造函数。

5.如下代码:c2对象无法创建,系统识别为函数的声明。 

#include<iostream>
using namespace std;
class Complex
{
private:
	int Real;
	int Image;
public:
	Complex()
	{
		Real = 0;//若不给值~为随机值
		Image = 0;
	}
	Complex(int x, int y)
	{
		Real = x;
		Image = y;
	}
};
int main()
{
	Complex c1;
	Complex c2();//c2对象无法创建,由于编译器会识别为函数的声明。
	Complex c3(12, 23);
	Complex c4 = Complex(1, 2);//编译器识别为:Complex c4(1,2);
	c4 = Complex(12, 25);//与上一句不同,先产生一个新对象,再赋值。
	Complex c5{};
	Complex c6{ 2,3 };//优先采用!
	return 0;
}

6.初始化!=赋值。初始化=构建对象时即赋值(效率高!)。

class Complex
{
private:
	int Real;
	int Image;
public:
	Complex():Real{},Image{} //Real(0),Image(0)
	{
		//Real = 0;
		//Image = 0;
	}
	Complex(int x, int y):Real{x},Image{y} //Real(x),Image(y) 初始化
	{
		//Real = x;//赋值
		//Image = y;
	}
};

如下代码:构造函数构建对象的次序是以类中成员属性设计的次序构建的!!与初始化列表次序无关。

#include<iostream>
using namespace std;
class Complex
{
private:
	int Real;
	int Image;
public:
	Complex(int x):Real{Image},Image{x}
	{
	}
	void Print()
	{
		cout << "Real=" << Real << "  Image=" << Image << endl;
	}
};
int main()
{
	Complex c1{3};
	c1.Print();
	return 0;
}

结果如图,Real先构建,是用随机值构建的:38407cef1cf949c4b89300fe7117f897.png

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这是DS小龙哥编写整理的C++入门指南PDF文档,适合C++初学者,C语言C++工程师当做入门工具书学习。PDF里有完整示例、知识讲解,平时开发都可以复制粘贴,非常便捷。 目前一共写了7章,后续会持续更新资源包,更新后重新下载即可。 这是目前书籍的目录: C++入门指南 1 一、 C++语言基本介绍与开发环境搭建 1 1.1 C++简介 1 1.2 面向对象编程 1 1.3 Windows系统下搭建C++学习环境 2 二、C++基础入门 16 2.1 C++类和对象 17 2.2 C++命名空间 18 2.3 std标准命名空间 20 2.4 C++新增的标准输入输出方法(cin和cout) 22 2.5 C++规定的变量定义位置 24 2.6 C++新增的布尔类型(bool) 24 2.7 C++ 新增的new和delete运算符 25 2.8 C++函数的默认参数(缺省参数) 26 2.9 C++函数重载详解 28 2.10 C++新增的引用语法 30 三、 C++面向对象:类和对象 34 3.1 类的定义和对象的创建 34 3.2 类的成员变量和成员函数 36 3.3 类成员的访问权限以及类的封装 38 3.4 C++类的构造函数与析构函数 39 3.5 对象数组 47 3.6 this指针 50 3.7 static静态成员变量 52 3.8 static静态成员函数 53 3.9 const成员变量和成员函数 55 3.10 const对象(常对象) 56 3.11 友元函数和友元类 58 3.11.3 友元类 61 3.12 C++字符串 62 四、C++面向对象:继承与派生 75 4.1 继承与派生概念介绍 75 4.2 继承的语法介绍 75 4.3 继承方式介绍(继承的权限) 76 4.4 继承时变量与函数名字遮蔽问题 79 4.5 基类和派生类的构造函数 82 4.6 基类和派生类的析构函数 83 4.7 多继承 85 4.8 虚继承和虚基类 88 五、C++多态与抽象类 91 5.1 多态概念介绍 91 5.2 虚函数 92 5.3 纯虚函数和抽象类 95 六、C++运算符重载 97 6.1 运算符重载语法介绍 97 6.2 可重载运算符与不可重载运算符 98 6.3 一元运算符重载 99 6.4 二元运算符重载 102 6.5 关系运算符重载 104 6.6 输入/输出运算符重载(>>、<<) 105 6.7 函数调用运算符 () 重载 106 6.8 重载[ ](下标运算符) 107 七、C++模板和泛型程序设计 108 7.1 函数模板 108 7.2 类模板 110

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值