【C++那些事儿】深入理解C++类与对象:从概念到实践(上)| 揭开this指针的神秘面纱

03-13 阅读 0评论

【C++那些事儿】深入理解C++类与对象:从概念到实践(上)| 揭开this指针的神秘面纱

【C++那些事儿】深入理解C++类与对象:从概念到实践(上)| 揭开this指针的神秘面纱,【C++那些事儿】深入理解C++类与对象:从概念到实践(上)| 揭开this指针的神秘面纱,词库加载错误:未能找到文件“C:\Users\Administrator\Desktop\火车头9.8破解版\Configuration\Dict_Stopwords.txt”。,使用,我们,访问,第2张
(图片来源网络,侵删)

📷 江池俊: 个人主页

🔥个人专栏: ✅数据结构冒险记 ✅C++那些事儿

🌅 有航道的人,再渺小也不会迷途。


【C++那些事儿】深入理解C++类与对象:从概念到实践(上)| 揭开this指针的神秘面纱

文章目录

    • 1. 面向过程和面向对象初步认识
    • 2.类的引入
    • 3.类的定义
    • 4.类的访问限定符及封装
      • 4.1 访问限定符
      • 【面试题】
        • 问题:C++中struct和class的区别是什么?
        • 4.2 封装
        • 【面试题】
          • 在类和对象阶段,主要是研究类的封装特性,那什么是封装呢?
          • 5.类的作用域
          • 6.类的实例化
          • 7.类对象模型
            • 7.1 如何计算类对象的大小
            • `问题:类中既可以有成员变量,又可以有成员函数,那么一个类的对象中包含了什么?如何计算一个类的大小?`
            • 7.2 类对象的存储方式猜测
              • 1. 对象中包含类的各个成员
              • 2. 代码只保存一份,在对象中保存存放代码的地址
              • 3. 只保存成员变量,成员函数存放在公共的代码段
              • 7.3 结构体内存对齐规则
              • 8.this指针
                • 8.1 this指针的引出
                • 8.2 this指针的特性
                • 【面试题】
                  • 1. this指针存在哪里?
                  • 2. this指针可以为空吗?
                  • 8.3. C语言和C++实现Stack的对比
                    • 1. C语言实现
                    • 2. C++实现

                      1. 面向过程和面向对象初步认识

                      C语言是面向过程的,关注的是过程,分析出求解问题的步骤,通过函数调用逐步解决问题。

                      【C++那些事儿】深入理解C++类与对象:从概念到实践(上)| 揭开this指针的神秘面纱

                      C++是基于面向对象的,关注的是对象,将一件事情拆分成不同的对象,靠对象之间的交互完成。

                      【C++那些事儿】深入理解C++类与对象:从概念到实践(上)| 揭开this指针的神秘面纱

                      【C++那些事儿】深入理解C++类与对象:从概念到实践(上)| 揭开this指针的神秘面纱,【C++那些事儿】深入理解C++类与对象:从概念到实践(上)| 揭开this指针的神秘面纱,词库加载错误:未能找到文件“C:\Users\Administrator\Desktop\火车头9.8破解版\Configuration\Dict_Stopwords.txt”。,使用,我们,访问,第6张
                      (图片来源网络,侵删)

                      2.类的引入

                      C语言结构体中只能定义变量,在C++中,结构体内不仅可以定义变量,也可以定义函数。比如:之前在数据结构初阶中,用C语言方式实现的栈,结构体中只能定义变量;现在以C++方式实现,会发现struct中也可以定义函数。

                      #include
                      #include
                      using namespace std;
                      typedef int DataType;
                      struct Stack
                      {
                      	// 初始化
                      	void Init(size_t capacity)
                      	{
                      		_array = (DataType*)malloc(sizeof(DataType) * capacity);
                      		if (nullptr == _array)
                      		{
                      			perror("malloc申请空间失败");
                      			return;
                      		}
                      		_capacity = capacity;
                      		_size = 0;
                      	}
                      	// 入栈
                      	void Push(const DataType& data)
                      	{
                      		// 扩容
                      		_array[_size] = data;
                      		++_size;
                      	}
                      	// 取栈顶元素
                      	DataType Top()
                      	{
                      		return _array[_size - 1];
                      	}
                      	// 销毁栈
                      	void Destroy()
                      	{
                      		if (_array)
                      		{
                      			free(_array);
                      			_array = nullptr;
                      			_capacity = 0;
                      			_size = 0;
                      		}
                      	}
                      	
                      	DataType* _array;
                      	size_t _capacity;
                      	size_t _size;
                      };
                      int main()
                      {
                      	Stack s;
                      	s.Init(10);
                      	s.Push(1);
                      	s.Push(2);
                      	s.Push(3);
                      	cout 
                      	// 类体:由成员函数和成员变量组成
                      };  // 一定要注意后面的分号
                      
                      public:
                      	void Init(int year)
                      	{
                      		// 这里的year到底是成员变量,还是函数形参?
                      		year = year;
                      	}
                      private:
                      	int year;
                      };
                      // 所以一般都建议这样
                      class Date
                      {
                      public:
                      	void Init(int year)
                      	{
                      		_year = year;
                      	}
                      private:
                      	int _year;
                      };
                      // 或者这样
                      class Date
                      {
                      public:
                      	void Init(int year)
                      	{
                      		mYear = year;
                      	}
                      private:
                      	int mYear;
                      };
                      // 其他方式也可以的。一般都是加个前缀或者后缀标识区分就行。
                      
                      public:
                      	// 成员函数声明
                      	void PrintPersonInfo();
                      private:
                      	char _name[20];
                      	char _gender[3];
                      	int  _age;
                      };
                      // 这里需要指定PrintPersonInfo是属于Person这个类域(成员函数类外定义)
                      void Person::PrintPersonInfo()
                      {
                      	cout 
                      	Person._age = 100;   // 编译失败:error C2059: 语法错误:“.”
                      	return 0;
                      }
                      
                      public:
                      	void PrintA()
                      	{
                      		cout 
                      public:
                      	void f1() {}
                      private:
                      	int _a;
                      };
                      // 类中仅有成员函数
                      class A2 
                      {
                      public:
                      	void f2() {}
                      };
                      // 类中什么都没有---空类
                      class A3
                      {};
                      int main()
                      {
                      	cout 
                      public:
                      	void Init(int year, int month, int day)
                      	{
                      		_year = year;
                      		_month = month;
                      		_day = day;
                      	}
                      	void Print()
                      	{
                      		cout 
                      	Date d1, d2;
                      	d1.Init(2022, 1, 11);
                      	d2.Init(2022, 1, 12);
                      	d1.Print();
                      	d2.Print();
                      	return 0;
                      }
                      
                      public:
                      	void PrintA()
                      	{
                      		cout 
                      	A* p = nullptr;
                      	p-PrintA();
                      	return 0;
                      }
                      // 答案:C、正常运行
                      // 原因:PrintA函数不在某个实例化的对象中,而是在公共代码区,所以p不会解引用,但是此处的p的作用是作为函数实参传递给函数第一个隐含的this指针。
                      // 1.下面程序编译运行结果是? A、编译报错 B、运行崩溃 C、正常运行
                      class A
                      {
                      public:
                      	void PrintA()
                      	{
                      		cout 
                      	A* p = nullptr;
                      	p-PrintA();
                      	return 0;
                      }
                      // 答案:B、运行崩溃
                      // 原因:PrintA函数中访问了成员函数_a,而_a的访问需要解引用this指针,但此时的this指针就是p,p是空指针,空指针解引用导致程序运行崩溃
                      
                      	DataType* array;
                      	int capacity;
                      	int size;
                      }Stack;
                      void StackInit(Stack* ps)
                      {
                      	assert(ps);
                      	ps-array = (DataType*)malloc(sizeof(DataType) * 3);
                      	if (NULL == ps-array)
                      	{
                      		assert(0);
                      		return;
                      	}ps-capacity = 3;
                      	ps-size = 0;
                      }
                      void StackDestroy(Stack* ps)
                      {
                      	assert(ps);
                      	if (ps-array)
                      	{
                      		free(ps-array);
                      		ps-array = NULL;
                      		ps-capacity = 0;
                      		ps-size = 0;
                      	}
                      }
                      void CheckCapacity(Stack* ps)
                      {
                      	if (ps-size == ps-capacity)
                      	{
                      		int newcapacity = ps-capacity * 2;
                      		DataType* temp = (DataType*)realloc(ps-array,
                      			newcapacity * sizeof(DataType));
                      		if (temp == NULL)
                      		{
                      			perror("realloc申请空间失败!!!");
                      			return;
                      		}
                      		ps-array = temp;
                      		ps-capacity = newcapacity;
                      	}
                      }
                      void StackPush(Stack* ps, DataType data)
                      {
                      	assert(ps);
                      	CheckCapacity(ps);
                      	ps-array[ps-size] = data;
                      	ps-size++;
                      }
                      int StackEmpty(Stack* ps)
                      {
                      	assert(ps);
                      	return 0 == ps-size;
                      }
                      void StackPop(Stack* ps)
                      {
                      	if (StackEmpty(ps))
                      		return;
                      	ps-size--;
                      }
                      DataType StackTop(Stack* ps)
                      {
                      	assert(!StackEmpty(ps));
                      	return ps-array[ps-size - 1];
                      }
                      int StackSize(Stack* ps)
                      {
                      	assert(ps);
                      	return ps-size;
                      }
                      int main()
                      {
                      	Stack s;
                      	StackInit(&s);
                      	StackPush(&s, 1);
                      	StackPush(&s, 2);
                      	StackPush(&s, 3);
                      	StackPush(&s, 4);
                      	printf("%d\n", StackTop(&s));
                      	printf("%d\n", StackSize(&s));
                      	StackPop(&s);
                      	StackPop(&s);
                      	printf("%d\n", StackTop(&s));
                      	printf("%d\n", StackSize(&s));
                      	StackDestroy(&s);
                      	return 0;
                      }
                      
                      public:
                      	void Init()
                      	{
                      		_array = (DataType*)malloc(sizeof(DataType) * 3);
                      		if (NULL == _array)
                      		{
                      			perror("malloc申请空间失败!!!");
                      			return;
                      		}
                      		_capacity = 3;
                      		_size = 0;
                      	}
                      	
                      	void Push(DataType data)
                      	{
                      		CheckCapacity();
                      		_array[_size] = data;
                      		_size++;
                      	}
                      	void Pop()
                      	{
                      		if (Empty())
                      			return;
                      		_size--;
                      	}
                      	DataType Top() { return _array[_size - 1]; }
                      	int Empty() { return 0 == _size; }
                      	int Size() { return _size; }
                      	void Destroy()
                      	{
                      		if (_array)
                      		{
                      			free(_array);
                      			_array = NULL;
                      			_capacity = 0;
                      			_size = 0;
                      		}
                      	}
                      private:
                      	void CheckCapacity()
                      	{
                      		if (_size == _capacity)
                      		{
                      			int newcapacity = _capacity * 2;
                      			DataType* temp = (DataType*)realloc(_array, newcapacity *sizeof(DataType));
                      			if (temp == NULL)
                      			{
                      				perror("realloc申请空间失败!!!");
                      				return;
                      			}
                      			_array = temp;
                      			_capacity = newcapacity;
                      		}
                      	}
                      private:
                      	DataType* _array;
                      	int _capacity;
                      	int _size;
                      };
                      int main()
                      {
                      	Stack s;
                      	s.Init();
                      	s.Push(1);
                      	s.Push(2);
                      	s.Push(3);
                      	s.Push(4);
                      	printf("%d\n", s.Top());
                      	printf("%d\n", s.Size());
                      	s.Pop();
                      	s.Pop();
                      	printf("%d\n", s.Top());
                      	printf("%d\n", s.Size());
                      	
                      	s.Destroy();
                      	return 0;
                      }
                      

免责声明
本网站所收集的部分公开资料来源于AI生成和互联网,转载的目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。
文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。

发表评论

快捷回复: 表情:
评论列表 (暂无评论,人围观)

还没有评论,来说两句吧...

目录[+]