C++的三元操作符
- if的语法糖
例1
#include <iostream>
#include <string>
static int s_Level = 1;
static int s_Speed = 2;
int main()
{
if (s_Level > 5)
{
s_Speed = 10;
}
else
{
s_Speed = 5;
}
std::cin.get();
}
用三元操作符:
s_Speed = s_Level > 5 ? 10 : 5;
若s_Level > 5, 则s_Speed = 10; 否则 s_Speed = 5.
std::string rank = s_Level > 10 ? "Master" : "Beginner";
三元操作符的嵌套
s_Speed = s_Level > 5 ? s_Level > 10 ? 15 : 10 : 5;
优先级
s_Speed = s_Level > 5 && s_Level < 100 ? s_Level > 10 ? 15 : 10 : 5;
三元运算符尽量不要做嵌套
创建并初始化C++对象
栈对象
- 有一个自动的生存期,由它声明的作用域决定的,只要变量超出作用域,其内存就会被释放
- 作用域结束,栈就会被弹出,所有栈上的东西都会被释放
例2
#include <iostream>
#include <string>
using String = std::string;
class Entity
{
private:
String m_Name;
public:
Entity() : m_Name("Unknown") {}
Entity(const String& name) : m_Name(name) {}
const String& GetName() const { return m_Name; }
};
int main()
{
Entity entity; // 栈对象,默认调用构造函数,C#或Java看起来奇怪,因为没有初始化
std::cout << entity.GetName() << std::endl;
Entity entity1("Cherno");
std::cout << entity1.GetName() << std::endl;
std::cin.get();
}
在{}作用域外,e指向的内容被释放掉:
int main()
{
Entity* e;
{
Entity entity;
std::cout << entity.GetName() << std::endl;
Entity entity1("Cherno");
e = &entity;
std::cout << entity1.GetName() << std::endl;
}
std::cin.get();
}
不在栈上创建对象的原因:
- 作用域外
- 需要创建很多对象,栈很小
堆对象
只要创建了,就会一直存在,直到手动删除它
例3
#include <iostream>
#include <string>
using String = std::string;
class Entity
{
private:
String m_Name;
public:
Entity() : m_Name("Unknown") {}
Entity(const String& name) : m_Name(name) {}
const String& GetName() const { return m_Name; }
};
int main()
{
Entity* e;
{
Entity entity; // 栈对象,默认调用构造函数,C#或Java看起来奇怪,因为没有初始化
std::cout << entity.GetName() << std::endl;
Entity* entity1 = new Entity("Cherno"); // 堆对象,C#或Java常看到的
e = entity1;
std::cout << (*entity1).GetName() << std::endl;
}
std::cin.get();
delete e;
}
作用域{}之外,e指向的内容仍然未被释放掉
C++new关键字
- new: 在堆上分配内存
- 用new需要找到连续的内存,搜索内存,像激光
- 空闲列表:维护那些空闲字节的地址
- new就是找到一块足够大的内存块,以满足我们的需求,然后它给我们一个指向那块内存的指针
例4
#include <iostream>
#include <string>
using String = std::string;
class Entity
{
private:
String m_Name;
public:
Entity() : m_Name("Unknown") {}
Entity(const String& name) : m_Name(name) {}
const String& GetName() const { return m_Name; }
};
int main()
{
int a = 2;
int* b = new int[50]; // 200 bytes
Entity* e = new Entity[50]; // 得到50个连续的Entity
Entity* e1 = new Entity(); // new不仅分配内存,还调用构造函数
std::cin.get();
}
new的源代码:就是一个操作符,操作符重载
new是一个函数,有一个分配得到的内存大小,返回一个空指针
指针只是内存地址;返回指针,size作为参数,返回一个指向那个分配的内存块的指针
new int[50]:
new关键字会调用隐藏在里面的c函数malloc:
malloc函数代表内存分配,传入一个size,然后返回一个空指针
所以,相当于重写了代码:Entity* e2 = (Entity*)malloc(sizeof(Entity));
, 但是这个不会调用构造函数
delete:
操作符
有block内存块
和size作为参数
调用了C函数free(),free可以释放malloc申请的内存
delete[] :
删除new的数组
指定new创建的地址
Entity* e3 = new(b) Entity();
假设Entity的大小是小于200字节的