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++——类型设计与实例化对象 的相关文章

  • 如何将 std::string& 转换为 C# 引用字符串

    我正在尝试将 C 函数转换为std string参考C 我的 API 如下所示 void GetStringDemo std string str 理想情况下 我希望在 C 中看到类似的东西 void GetStringDemoWrap r
  • 在 xaml 中编写嵌套类型时出现设计时错误

    我创建了一个用户控件 它接受枚举类型并将该枚举的值分配给该用户控件中的 ComboBox 控件 很简单 我在数据模板中使用此用户控件 当出现嵌套类型时 问题就来了 我使用这个符号来指定 EnumType x Type myNamespace
  • 如何从本机 C(++) DLL 调用 .NET (C#) 代码?

    我有一个 C app exe 和一个 C my dll my dll NET 项目链接到本机 C DLL mynat dll 外部 C DLL 接口 并且从 C 调用 C DLL 可以正常工作 通过使用 DllImport mynat dl
  • 如何使从 C# 调用的 C(P/invoke)代码“线程安全”

    我有一些简单的 C 代码 它使用单个全局变量 显然这不是线程安全的 所以当我使用 P invoke 从 C 中的多个线程调用它时 事情就搞砸了 如何为每个线程单独导入此函数 或使其线程安全 我尝试声明变量 declspec thread 但
  • 用于 FTP 的文件系统观察器

    我怎样才能实现FileSystemWatcherFTP 位置 在 C 中 这个想法是 每当 FTP 位置添加任何内容时 我都希望将其复制到我的本地计算机 任何想法都会有所帮助 这是我之前问题的后续使用 NET 进行选择性 FTP 下载 ht
  • 对类 static constexpr 结构的未定义引用,g++ 与 clang

    这是我的代码 a cp p struct int2 int x y struct Foo static constexpr int bar1 1 static constexpr int2 bar2 1 2 int foo1 return
  • 需要帮助优化算法 - 两百万以下所有素数的总和

    我正在尝试做一个欧拉计划 http projecteuler net问题 我正在寻找 2 000 000 以下所有素数的总和 这就是我所拥有的 int main int argc char argv unsigned long int su
  • 方程“a + bx = c + dy”的积分解

    在等式中a bx c dy 所有变量都是整数 a b c and d是已知的 我如何找到整体解决方案x and y 如果我的想法是正确的 将会有无限多个解 由最小公倍数分隔b and d 但我只需要一个解决方案 我可以计算其余的 这是一个例
  • 人脸 API DetectAsync 错误

    我想创建一个简单的程序来使用 Microsoft Azure Face API 和 Visual Studio 2015 检测人脸 遵循 https social technet microsoft com wiki contents ar
  • 两个类可以使用 C++ 互相查看吗?

    所以我有一个 A 类 我想在其中调用一些 B 类函数 所以我包括 b h 但是 在 B 类中 我想调用 A 类函数 如果我包含 a h 它最终会陷入无限循环 对吗 我能做什么呢 仅将成员函数声明放在头文件 h 中 并将成员函数定义放在实现文
  • 实例化类时重写虚拟方法

    我有一个带有一些虚函数的类 让我们假设这是其中之一 public class AClassWhatever protected virtual string DoAThingToAString string inputString retu
  • 空指针与 int 等价

    Bjarne 在 C 编程语言 中写道 空指针与整数零不同 但 0 可以用作空指针的指针初始值设定项 这是否意味着 void voidPointer 0 int zero 0 int castPointer reinterpret cast
  • 如何在 Linq to SQL 中使用distinct 和 group by

    我正在尝试将以下 sql 转换为 Linq 2 SQL select groupId count distinct userId from processroundissueinstance group by groupId 这是我的代码
  • 如何在 Android 中使用 C# 生成的 RSA 公钥?

    我想在无法假定 HTTPS 可用的情况下确保 Android 应用程序和 C ASP NET 服务器之间的消息隐私 我想使用 RSA 来加密 Android 设备首次联系服务器时传输的对称密钥 RSA密钥对已在服务器上生成 私钥保存在服务器
  • 有没有办法让 doxygen 自动处理未记录的 C 代码?

    通常它会忽略未记录的 C 文件 但我想测试 Callgraph 功能 例如 您知道在不更改 C 文件的情况下解决此问题的方法吗 设置变量EXTRACT ALL YES在你的 Doxyfile 中
  • C++ 中的参考文献

    我偶尔会在 StackOverflow 上看到代码 询问一些涉及函数的重载歧义 例如 void foo int param 我的问题是 为什么会出现这种情况 或者更确切地说 你什么时候会有 对参考的参考 这与普通的旧参考有何不同 我从未在现
  • 指针和内存范围

    我已经用 C 语言编程有一段时间了 但对 C 语言还是很陌生 有时我对 C 处理内存的方式感到困惑 考虑以下有效的 C 代码片段 const char string void where is this pointer variable l
  • Mono 应用程序在非阻塞套接字发送时冻结

    我在 debian 9 上的 mono 下运行一个服务器应用程序 大约有 1000 2000 个客户端连接 并且应用程序经常冻结 CPU 使用率达到 100 我执行 kill QUIT pid 来获取线程堆栈转储 但它总是卡在这个位置
  • 现代编译器是否优化乘以 1 和 -1

    如果我写 template
  • 从 mvc 控制器使用 Web api 控制器操作

    我有两个控制器 一个mvc控制器和一个api控制器 它们都在同一个项目中 HomeController Controller DataController ApiController 如果我想从 HomeController 中使用 Dat

随机推荐