【C++】类和对象(1)(基本知识)

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

引入

C语言结构体中只能定义变量,在C++中,结构体内不仅可以定义变量,也可以定义函数。
比如:

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;
}};

类的定义

相较于struct,在C++中更喜欢用class来定义类:

class className
{
// 类体:由成员函数和成员变量组成
};

类有两种定义方式

  1. 声明和定义全部放在类体中,需注意:成员函数如果在类中定义,编译器可能会将其当成内
    联函数处理。
  2. 类声明放在.h文件中,成员函数定义放在.cpp文件中,注意:成员函数名前需要加类名::
    一般最好使用第二种定义方式

访问限定符

1.public
2.protected
3.private

说明:

1.Public 成员: 在类或结构体中声明为 public 的成员可以在类或结构体的外部直接被访问。这意味着它们可以从类或结构体的任何地方访问,包括类或结构体的外部。
2.Protected 成员: protected 成员在类的外部不可直接访问,但是在派生类中是可以访问的。这意味着继承自基类的派生类可以访问 protected 成员,而外部代码不可以。
3.Private 成员: private 成员只能在声明它的类内部访问。类的外部以及派生类都无法直接访问 private 成员。 访问权限的作用域:
4.访问权限限定符(如 public、protected 或 private)的作用域从它们出现的地方开始,一直延伸到下一个访问限定符出现之前。如果没有后续的访问限定符,则作用域持续到类的结束括号 }。
5.默认访问权限: class 的默认访问权限是 private。这意味着如果没有显式指定访问级别,所有的成员都是 private 的。 struct 的默认访问权限是 public。这是为了让 struct 兼容 C 语言,在 C++ 中这样可以保持向后兼容性。

封装

面向对象的三大特性:封装,继承,多态。
封装的本质是一种管理,C++的数据和方法都放在类里,访问限定符可对访问成员进行限制。

作用域

类定义了一个新的作用域,类的所有成员都在类的作用域中。
在类外定义成员时,需要用 类名::来指定类域

实例化

类的定义并没有开辟空间,类是对对象进行描述的,限定了类有哪些成员,定义出一个类并没
有分配实际的内存空间来存储它;
用类类型创建对象的过程,称为类的实例化 一个类可以实例化出多个对象,实例化出的对象 占用实际的物理空间,存储类成员变量

class Date{
public:
void Print()
	{
		cout << _year << "/" << _month << "/" << _day << endl;
	}
private:
	int _year;
	int _month;
	int _day;
};
int main()
{
Date d1;  //这个是类的实例化
Date d2;
}

变量定义的标志是开辟了空间,声明时没有开空间,对象实例化(定义)的时候才分配了空间。

类的大小

成员函数放在了公共区域,计算类变量大小时不考虑成员函数的大小,一个类的大小,实际就是该类中”成员变量”之和,要注意内存对齐(
同结构体内存对齐规则https://blog.csdn.net/2301_78696090/article/details/141928933),没有成员变量的类对象大小为1字节,表示对象实例化时,定义出来存在。

this指针

C++编译器给每个“非静态的成员函数“增加了一个隐藏的指针参数,让该指针指向当前对象(函数运行时调用该函数的对象),在函数体中所有“成员变量”的操作,都是通过该指针去访问。这个指针就是this指针。

静态成员函数属于类而不属于某个特定的对象实例。
因此,静态成员函数不需要也不应该访问任何非静态的数据成员或非静态成员函数,因为它们没有与特定对象实例绑定。

this指针特性:

  1. this指针的类型:* const,即不能给this指针赋值。
  2. this指针只能在“成员函数”的内部使用。
  3. this指针本质上是“成员函数”的形参,当对象调用成员函数时,将对象地址作为实参传递给this形参。所以对象中不存储this指针。
  4. this指针是“成员函数”第一个隐含的指针形参,一般情况由编译器通过ecx寄存器自动传递,不需要用户传递。

由此例来解释this指针是如何起作用的

#include <iostream>
using namespace std;
class MyClass {
public:
    void printThis() {
        std::cout << "This pointer value: " << this << std::endl;
    }
};

int main() {
    MyClass obj;

    // 调用成员函数printThis()并传递this指针
    obj.printThis();
    cout << &obj << endl;
    return 0;
}

运行结果:

This pointer value: 000000C4962FF764
000000C4962FF764

在main()函数中,我们创建了一个MyClass对象obj,然后调用了它的成员函数printThis()。当我们调用成员函数时,编译器会自动将对象的地址作为隐式参数传递给成员函数,因此在printThis()函数内部,this指针指向了调用该函数的对象的地址。

由运行结果不难看出this指针的值与obj的地址值相同。

为了进一步理解this指针,下面有两道例题:

> // 1.下面程序编译运行结果是? A、编译报错 B、运行崩溃 C、正常运行

class A
{
public:
 void Print()
 {
 cout << "Print()" << endl;
 }
private:
 int _a;
};
int main()
{
 A* p = nullptr;
 p->Print();
 return 0;
}
> // 2.下面程序编译运行结果是? A、编译报错 B、运行崩溃 C、正常运行
class A
{ 
public:
    void PrintA() 
   {
        cout<<_a<<endl;
   }
private:
 int _a;
};
int main()
{
    A* p = nullptr;
    p->PrintA();
    return 0;
}

1可以正常运行,2会运行崩溃。
1中由于PrintA()不在p指向的空间,只是空指针的传递,没有解引用。
而2中_a在指针p指向的空间里,this->_a,会解引用空指针,导致运行崩溃。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值