0
点赞
收藏
分享

微信扫一扫

C++-类与对象(上)

janedaring 2023-10-28 阅读 35

一、

auto关键字

1.自动识别数据类型

2.auto的初始化

3.auto简化for循环

nullptr的使用

二、类与对象

1.c++中类的定义

2.c语言与c++的比较

3.类的访问限定符以及封装

3.1访问限定符

3.2封装

3.3类的作用域

3.4类的声明与定义分离


一、

auto关键字

auto的意义:类型名字较长时使用auto来定义比较方便

1.自动识别数据类型

auto关键字可以自动识别数据的类型,我们可以是typeid()name.()函数来查看一个数据的类型

int main()
{
	int a = 0;
	int b = a;
	auto c = a;
	auto d = &a;
	auto* e = &a;
	int& f = a;
	cout << typeid(c).name() << endl;
	cout << typeid(d).name() << endl;
	cout << typeid(e).name() << endl;
	cout << typeid(f).name() << endl;
	return 0;
}

下面是运行结果

上面只是auto用法的一个小小小小小的用法。

2.auto的初始化

auto初始化时必须在右边给个值进行初始化,不然auto无法识别数据的类型

auto=x; //对auoto错误的初始化

auto x=1.0;
auto x=1.22;

需要注意的是auto不能作为函数的参数,也不能作为一个函数的返回值,与此同时auto也不能用来声明数组

3.auto简化for循环

int main()
{
int array[] = { 1,2,3,4,5 };
	for (int i = 0; i < sizeof(array) / sizeof(array[0]); i++)
	{
		array[i] *= 2;
	}
	for (int* p = array; p < array + sizeof(array) / sizeof(array[0]); ++p)
	{
		cout << *p << endl;
	}
	for (auto e : array)
	{
		cout << e << "";
	}
	cout << endl;
	return 0;
}

auto在这里的作用:依次取数组中的数字赋值给e,并且自动判断结束,自动++往后走。

int main()
{
for (auto e : array)
	{
		e++;
		cout << e << "";
	}
	cout << endl;
	for (auto e : array)
	{
		cout << e << "";

	}
	cout << endl;
	return 0;
}

如果想要通过修改e来对数组内容进行修改,可以使用 引用

int main()
{
for (auto &e : array)
	{
		e++;
		cout << e << "";
	}
	cout << endl;
	for (auto e : array)
	{
		cout << e << "";

	}
	cout << endl;
	return 0;
}

eg:c语言为了效率,数组是不能够传参的,一般是使用数组的首元素的地址进行传参的。

nullptr的使用

c语言中的NULL本质上是一个宏定义,#define NULL 0

在c++中 为了弥补这一缺陷,使用了nullptr来替换NULL

二、类与对象

1.c++中类的定义

class className
{
// 类体:由成员函数和成员变量组成
};  // 一定要注意后面的分号

class 为定义类的关键字ClassName 为类的名字{} 中为类的主体,注意类定义结束时后面分 号不能省略。

类体中内容称为类的成员类中的变量称为类的属性或成员变量; 类中的函数称为类的方法或者成员函数。

类的两种定义方式:

1.声明和定义全部放在类体中,需注意:成员函数如果在类中定义,编译器可能会将其当成内联函数处理

//定义一个人
class People
{
public:
	void show()
	{
		cout << _name << "-" << _sex << "-" << _age << endl;
	}
public:
	char* _name; //姓名
	char* _sex;  //性别
	int _age;    //年龄
};

2,类声明放在 .h 文件中,成员函数定义放在 .cpp 文件中,注意:成员函数名前需要加类名::    以此来进入对应的域中

People.h
 
//人
class People
{
public:
	void show();
public:
	char* _name; //姓名
	char* _sex;  //性别
	int _age;    //年龄
};
 
People.cpp
 

void Person::show()
{
	cout << _name << "-" << _sex << "-" << _age << endl;
}

2.c语言与c++的比较

c++向下兼容所有c语言struct所有的用法

struct同时升级成了类

1、类名就是类型,Stack就是类型,不需要加struct

2、函数的定义都放在了类中

下面这一段是c语言对栈进行初始化

//C语言
struct Stack
{
 int* a;
 int top;
 int capacity;
};

void StackInit(struct Stack* ps);
void StackPush(struct Stack* ps, int x);

 下面是c++的一段

class Stack
{
private:
	int* a;
	int top;
	int capacity;

public:
	void Init()
	{
		a = 0;
		top = 0;
		capacity = 0;
	}

	void Push(int x)
	{
		//...
	}

	bool Empty()
	{
		return top == 0;
	}
};

3.类的访问限定符以及封装

3.1访问限定符

C++实现封装的方式: 用类将对象的属性与方法结合在一块,让对象更加完善,通过访问权限选择性的将其接口提供给外部的用户使用。

这里有一道关于struct和class的面试题:

C++ 中 struct 和 class 的区别是什么?

3.2封装

  • 封装可以隐藏实现细节,使得代码模块化,使代码和功能独立
  • 封装是把函数和数据包围起来,对数据的访问只能通过可信任的对象和类进行访问,对不可信的进行信息隐藏。
  • 封装本质上是一种管理,让用户更方便使用类。

3.3类的作用域

class Person
{
public:
	void PrintPersonInfo();
private:
	char _name[20];
	char _gender[3];
	int  _age;
};
// 这里需要指定PrintPersonInfo是属于Person这个类域
void Person::PrintPersonInfo()
{
	cout << _name << " " << _gender << " " << _age << endl;
}

 访问时如果不加作用域操作符号,编译器就不知道应该调用哪一个域内的函数。

c++中花括号定义的都是域

3.4类的声明与定义分离

//Stack.h文件
class Stack
{
private:
	int* a;
	int top;
	int capacity;
public:
	void Init();
	void Push(int x);
	bool Empty();
};
//Stack.cpp文件
void Stack::Init()
{
	a = 0;
	top = 0;
	capacity = 0;
}
void Stack::Push(int x)
{
	//....
}

 3.5成员变量命名规则

class Date
{
public:
	void Init(int year)
	{
		year = year;
	}
private:
	string year;
};
 
int main()
{
	return 0;
}

看到这个函数我们不免发出疑问,调用Init的这个函数中 两个year,哪一个是成员变量,哪一个是函数的形参,这样的写法使得阅读代码的人一个头两个大。所以我们可以在成员变量前加上一个下划线来区分形参和成员变量

class Date
{
public:
	void Init(int year)
	{
		_year = year;
	}
private:
	int _year;
};

 3.6内存对齐规则

 3.7类中对象的存储方式

 类的大小,根据内存对齐规则可以求得

需要注意的是:一个类的大小就是通过内存对齐规则后求得的大小,特殊的是我们要注意空类的大小,空类比较特殊,编译器给了空类一个字节来唯一标识这个类的对象。

class Date
{
public:
	void Init(int year, int month, int day)
	{
		_year = year;
		_month = month;
		_day = day;
	}

//private:
	// 声明
	int _year;
	int _month;
	int _day;
};

class A
{
private:
	char _ch;
	int _a;
};

class B
{};

class C
{
public:
	void f()
	{};
};
int main()
{
	Date d1;
	Date d2;
	Date d3;

	cout << sizeof(d1) << endl;
	cout << sizeof(A) << endl;

	B b1;
	B b2;

	cout << sizeof(B) << endl;
	cout << sizeof(C) << endl;

	// 无成员变量的类,对象大小开一个字节,这个字节不存储有效数据
	// 标识定义的对象存在过

	return 0;
}

 

类B与类C的大小都是1。

3.8 this指针

我们先来看下面这样一段代码

class Date
{
public:
	void Init(int year, int month, int day)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	void Print()
	{
		cout << _year << "-" << _month << "-" << _day << endl;
	}
private:
	int _year;     // 年
	int _month;    // 月
	int _day;      // 日
};
int main()
{
	Date d1, d2;
	d1.Init(2022, 1, 11);
	d2.Init(2023, 1, 12);
	d1.Print();
	d2.Print();
	return 0;
}

 

 3.9this指针的一些性质

1.this指针的类型是const *类型,不能写this相关的实参和形参,不能给this指针赋值

2.只能在成员函数内部使用

3.this指针能在类中显示调用

4.this指针是个形参,存储在栈帧上,不是存储在对象中的


总结

举报

相关推荐

0 条评论