箭头操作符&&动态数组(C++基础)

在学习这节课之前,复习了一下之前的代码:

class Entity{
public:
	int x, y;
    Entity(int x,int y): x(x),y(y) { std::cout << "created" << std::endl; }
};
	Entity e(1,1);
	Entity* e1 = &e;
	Entity& e2 = *e1;
	Entity e3(3, 3);
	e2 = e3;
	e2.x = 2;
	std::cout << e3.x << std::endl; 
	std::cout << e.x << std::endl;

输出3,2

e2引用后e就不能改变对象,哪怕不会报错,但对e2操作还是会操作在e上,而不是e3。使用引用来避免数据复制,参数传递、返回值、运算符重载等等都会用到。

箭头操作符

一般在指针对对象访问的情况使用,有时还会用到操作符重载,如下:

class Entity{
public:
	int x, y;
	void Print() const {
		std::cout << "hello!" << std::endl;
	}
};

class ScopedPtr {
private:
	Entity* m_Obj;
public:
	ScopedPtr(Entity* entity):m_Obj(entity) {}
 	~ScopedPtr() {
		delete m_Obj;
	}
	Entity* GetObj() {
		return m_Obj;
	}
	const Entity* operator->() const {
		return m_Obj;
	}
};

使用智能指针的情况下要使用重载符号,不然只能手动编写Get方法来获取对象指针(记得使用const)

	ScopedPtr entity = new Entity();
	entity->Print();//方法中要记得带const
	entity.GetObj()->Print();

虽然下面两条语句意思一样,但使用智能指针可以自动释放内存,更为方便~

	const ScopedPtr entity = new Entity();
	const Entity* entity = new Entity();

当把数据序列化为一串字节流的时候,当你想要计算某些东西的偏移量的时候,会用到下面代码:

struct Vector3 {
	float x, z, y;//找出y在内存中的偏移量4
};
	int offset = (int)&((Vector3*)nullptr)->z;
	std::cout << offset << std::endl;

动态数组

缓存线上存储更快,尽量使用对象而不是指针,指针是最后的选择。

动态数组指vector,声明语句:

#include<vector>
std::vector<Vertex> vertices;

添加语句:

vertices.push_back({1,2,3});

遍历语句(如果是类对象,需要重载<<操作符):

std::ostream& operator<<(std::ostream& stream, const Vertex& vertex)  {
	stream << vertex.x << "," << vertex.y << "," << vertex.z;
	return stream;
}	
    for (int i = 0; i < vertices.size();i++) {
		std::cout << vertices[i] << std::endl;
	}
	for (Vertex& v : vertices) {
		std::cout << v << std::endl;
	}//不加引用符就会复制

删除某个数据内容:

vertices.erase(vertices.begin() + 1);

清空数组:

vertices.clear();

全部代码如下:

#include<iostream>
#include<string>
#include<vector>
struct Vertex {
	float x, y, z;
};

std::ostream& operator<<(std::ostream& stream, const Vertex& vertex)  {
	stream << vertex.x << "," << vertex.y << "," << vertex.z;
	return stream;
}
void Function(const std::vector<Vertex>& vertices){
	
}

int main() {
	std::vector<Vertex> vertices;
	//缓存线上存储更快,尽量使用对象而不是指针,指针是最后的选择
	vertices.push_back({1,2,3});
	vertices.push_back({4,5,6});

	Function(vertices);
	for (int i = 0; i < vertices.size();i++) {
		std::cout << vertices[i] << std::endl;
	}
	vertices.erase(vertices.begin() + 1);
	for (Vertex& v : vertices) {
		std::cout << v << std::endl;
	}//不加引用符就会复制
	vertices.clear();
	std::cin.get();

}

数组优化:

struct Vertex {
	float x, y, z;
	Vertex(float x, float y, float z) : x(x), y(y), z(z) {}
	Vertex(const Vertex& vertex) : x(vertex.x), y(vertex.z), z(vertex.z) {
		std::cout << "Copied!" << std::endl;
	}
};
std::ostream& operator<<(std::ostream& stream, const Vertex& vertex) {
	stream << vertex.x << "," << vertex.y << "," << vertex.z;
	return stream;
}

    std::vector<Vertex> vertices;
	vertices.push_back(Vertex({ 1, 2, 3 }));
	vertices.push_back(Vertex({ 1, 2, 3 }));
	vertices.push_back(Vertex({ 1, 2, 3 }));

运行结果:

为什么会发生六次呢?首先要先弄清楚,在main函数中,是一个栈来存储的,要想将vertex复制到vector中,这是三个对象分别copied的问题,其次是在数组扩容时需要修改之前的存储对象的指向。优化策略如下:


int main() {
	std::vector<Vertex> vertices;
	//缓存线上存储更快,尽量使用对象而不是指针,指针是最后的选择
	vertices.reserve(3);
	vertices.emplace_back(1,2,3);
	vertices.emplace_back(4,5,6);
	vertices.emplace_back(7,8,9 );
	//vertices.push_back(Vertex({ 7,8,9 }));
	std::cin.get();

}

分别使用reserve语句预设了空间,和vertices.emplace_back(1,2,3);直接构造对象,结果指针没有复制,那emplace_back岂不是任何时候都可以替换push_back,答案当然不是,因此查询了相关资料,弄清楚了两者的区别。

在某些情况下,使用emplace_back可能比push_back更高效,因为它避免了不必要的拷贝或移动操作。然而,并非所有情况都适合使用emplace_back。如果对象的构造过程非常简单,或者对象的复制或移动成本很低,那么使用push_back可能更合适。

  • 7
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

想进大厂~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值