2022.6.1 C++——类型设计与实例化对象

2023-11-01


对象是类的实例,声明一种数据类型只是告诉编译系统该数据类型的构造,并没有预定内存;类只是一个样板(图纸),以此样板可以在内存中开辟出同样结构的实例——对象。
创建类的对象可以有两种常用方法:直接定义类的实例——对象和用指针。

对象的创建与使用

1 直接定义类的实例——对象

如:
在这里插入图片描述
这个定义创建了CGoods类的一个对象car,同时为它分配了属于它自己的存储块,用来存放数据和对这些数据实施操作的成员函数(代码);对象只在定义它的域中有效。
对象的使用:
在这里插入图片描述
总结:对象的使用规则很简单,只要在对象名后加点号(点操作符——成员访问运算符之一),再加成员数据或成员函数名就可以了,但是这些成员必须是公有的成员,只有公有的成员才能在对象的外面对它进行访问。

2 C++对象模型讨论

方案一:各对象完全独立地安排内存的方案
在这里插入图片描述
上图是系统为每一个对象分配了全套的内存,包括安放成员数据的数据区和安放成员函数的代码区,但是区别同一个类所实例化的对象,是由属性(数据成员)的值决定,不同对象的数据成员的内容是不一样的;而行为(操作)是用函数来描述的,这些操作的代码对所有的对象都是一样的。
方案二:各对象的代码区共有的方案
在这里插入图片描述
方案二中的图仅为每个对象分配一个数据区,代码区(放成员函数的区域)为各对象类共用。
总结:对象那个模型中的存储区分配,如果代码区共享的话,会节省很多内存空间。
如:
在这里插入图片描述
当tea.RegisterGoods(“black_tea”, 12, 560);处理时,RegisterGoods其实是通过一个this指针来处理的。

3 this指针的作用

编译器针对程序员自己设计的类型分三次编译:
第一次:识别和记录类体中属性的名称,类型和访问限定,与属性在类体中的位置无关;如 class CGoods中的Name,Amount,Price,Total;
第二次:识别和记录类体中函数原型(返回类型+函数名+参数列表),形参的默认值,访问限定;
第三次:改写在类中定义函数的参数列表和函数体,改写对象调用成员函数的形式。
如:原代码为:

#include<iostream>
using namespace std;
class CGoods
{
private:
	char Name[21];  //商品名称
	int Amount;     //数量
	float Price;    //单价
	float Total;    //总价
public:
	void RegisterGoods(const char [], int, float);//输入数据
	void CountTotal(void);     //计算商品总价值
};
void CGoods::RegisterGoods(const char name[], int amount, float price)
{
	strcpy(Name, name);//字符串拷贝函数
	Amount = amount;
	Price = price;
}
void CGoods::CountTotal( )
{
	Total = Price * Amount;
}
int main()
{
	CGoods tea;
	CGoods book;
	tea.RegisterGoods("black_tea", 12, 560);
	tea.CountTotal();
	book.RegisterGoods("Thinking in C++", 20, 128);
	book.CountTotal();
	return 0;
}

改写后:

#include<iostream>
using namespace std;
class CGoods
{
private:
	char Name[21];  //商品名称
	int Amount;     //数量
	float Price;    //单价
	float Total;    //总价
public:

	void RegisterGoods(const char [], int, float);
	//void RegisterGoods(CGoods *const this, char [], int ,float);
	void CountTotal(void);   
	//void CountTotal(CGoods *const this);
};
//void CGoods::RegisterGoods(CGoods *const this,char name[], int amount, float price);
void CGoods::RegisterGoods(const char name[], int amount, float price)
{
	strcpy(this->Name, name);//字符串拷贝函数
	this->Amount = amount;
	this->Price = price;
}
//void CGoods::CountTotal(CGoods *const this);
void CGoods::CountTotal( )
{
	this->Total = this->Price * this->Amount;
}
int main()
{
	CGoods tea;
	CGoods book;
	tea.RegisterGoods("black_tea", 12, 560);
	//RegisterGoods(&tea,"black_tea", 12, 560);
	tea.CountTotal();
	//CountTotal(&tea);
	book.RegisterGoods("Thinking in C++", 20, 128);
	//RegisterGoods(&tea,"Thinking in C++", 20, 128);
	book.CountTotal();
	//CountTotal(&book);
	return 0;
}

注意:其中//之后是改正的,可以看出,this指针在代码中其实是隐形存在的,而且this指针不占用内存。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

2022.6.1 C++——类型设计与实例化对象 的相关文章

  • 如何在MVVM中管理多个窗口

    我知道有几个与此类似的问题 但我还没有找到明确的答案 我正在尝试深入研究 MVVM 并尽可能保持纯粹 但不确定如何在坚持模式的同时启动 关闭窗口 我最初的想法是向 ViewModel 发送数据绑定命令 触发代码来启动一个新视图 然后通过 X
  • 检查两个数是否是彼此的排列?

    给定两个数字 a b 使得 1 例如 123 是 312 的有效排列 我也不想对数字中的数字进行排序 如果您指的是数字的字符 例如 1927 和 9721 则 至少 有几种方法 如果允许排序 一种方法是简单地sprintf将它们放入两个缓冲
  • 如何检查图像对象与资源中的图像对象是否相同?

    所以我试图创建一个简单的程序 只需在单击图片框中更改图片即可 我目前只使用两张图片 所以我的图片框单击事件函数的代码 看起来像这样 private void pictureBox1 Click object sender EventArgs
  • 如何验证文件名称在 Windows 中是否有效?

    是否有一个 Windows API 函数可以将字符串值传递给该函数 该函数将返回一个指示文件名是否有效的值 我需要验证文件名是否有效 并且我正在寻找一种简单的方法来完成此操作 而无需重新发明轮子 我正在直接使用 C 但针对的是 Win32
  • ASP.NET Core Serilog 未将属性推送到其自定义列

    我有这个设置appsettings json对于我的 Serilog 安装 Serilog MinimumLevel Information Enrich LogUserName Override Microsoft Critical Wr
  • 使闭包捕获的变量变得易失性

    闭包捕获的变量如何与不同线程交互 在下面的示例代码中 我想将totalEvents 声明为易失性的 但C 不允许这样做 是的 我知道这是错误的代码 这只是一个例子 private void WaitFor10Events volatile
  • 在 Visual Studio 2008 上设置预调试事件

    我想在 Visual Studio 中开始调试程序之前运行一个任务 我每次调试程序时都需要运行此任务 因此构建后事件还不够好 我查看了设置的 调试 选项卡 但没有这样的选项 有什么办法可以做到这一点吗 你唯一可以尝试的 IMO 就是尝试Co
  • C - 找到极限之间的所有友好数字

    首先是定义 一对友好的数字由两个不同的整数组成 其中 第一个整数的除数之和等于第二个整数 并且 第二个整数的除数之和等于第一个整数 完美数是等于其自身约数之和的数 我想做的是制作一个程序 询问用户一个下限和一个上限 然后向他 她提供这两个限
  • 如果使用 SingleOrDefault() 并在数字列表中搜索不在列表中的数字,如何返回 null?

    使用查询正数列表时SingleOrDefault 当在列表中找不到数字时 如何返回 null 或像 1 这样的自定义值 而不是类型的默认值 在本例中为 0 你可以使用 var first theIntegers Cast
  • WPF TabControl,用C#代码更改TabItem的背景颜色

    嗨 我认为这是一个初学者的问题 我搜索了所有相关问题 但所有这些都由 xaml 回答 但是 我需要的是后台代码 我有一个 TabControl 我需要设置其项目的背景颜色 我需要在选择 取消选择和悬停时为项目设置不同的颜色 非常感谢你的帮助
  • 在 ASP.NET Core 3.1 中使用包含“System.Web.HttpContext”的旧项目

    我们有一些用 Net Framework编写的遗留项目 应该由由ASP NET Core3 1编写的API项目使用 问题是这些遗留项目正在使用 System Web HttpContext 您知道它不再存在于 net core 中 现在我们
  • Discord.net 无法在 Linux 上运行

    我正在尝试让在 Linux VPS 上运行的 Discord net 中编码的不和谐机器人 我通过单声道运行 但我不断收到此错误 Unhandled Exception System Exception Connection lost at
  • C++ 复制初始化和直接初始化,奇怪的情况

    在继续阅读本文之前 请阅读在 C 中 复制初始化和直接初始化之间有区别吗 https stackoverflow com questions 1051379 is there a difference in c between copy i
  • 控制到达非 void 函数末尾 -wreturn-type

    这是查找四个数字中的最大值的代码 include
  • 在 Dynamics CRM 插件中访问电子邮件发件人地址

    我正在编写一个 Dynamics CRM 2011 插件 该插件挂钩到电子邮件实体的更新后事件 阶段 40 pipeline http msdn microsoft com en us library gg327941 aspx 并且在此阶
  • 32 位到 64 位内联汇编移植

    我有一段 C 代码 在 GNU Linux 环境下用 g 编译 它加载一个函数指针 它如何执行并不重要 使用一些内联汇编将一些参数推送到堆栈上 然后调用该函数 代码如下 unsigned long stack 1 23 33 43 save
  • 为什么 C# Math.Ceiling 向下舍入?

    我今天过得很艰难 但有些事情不太对劲 在我的 C 代码中 我有这样的内容 Math Ceiling decimal this TotalRecordCount this PageSize Where int TotalRecordCount
  • 为什么我收到“找不到编译动态表达式所需的一种或多种类型。”?

    我有一个已更新的项目 NET 3 5 MVC v2 到 NET 4 0 MVC v3 当我尝试使用或设置时编译出现错误 ViewBag Title财产 找不到编译动态表达式所需的一种或多种类型 您是否缺少对 Microsoft CSharp
  • const、span 和迭代器的问题

    我尝试编写一个按索引迭代容器的迭代器 AIt and a const It两者都允许更改容器的内容 AConst it and a const Const it两者都禁止更改容器的内容 之后 我尝试写一个span
  • x86 上未对齐的指针

    有人可以提供一个示例 将指针从一种类型转换为另一种类型由于未对齐而失败吗 在评论中这个答案 https stackoverflow com questions 544928 reading integer size bytes from a

随机推荐