1. const关键字
1.1 const的使用场景
1.2 const&和const的区别
在函数参数中加了const&和const
fun(const std::string str, const std::string& str)
{
}
如果是const(不加引用)
,那么const std::string str
会复制一份,调用拷贝构造函数,在函数内部不可对其进行改变。
如果是const &
,那么传入的值,就是str
,不会调用拷贝构造函数,在函数内部不可对其进行改变。
因此,两者的区别如下:
(1)在函数参数中加了&
,相当于不会调用拷贝构造函数,即const &
会少调用一次拷贝构造。
(2)如果你不想在函数内部改变其函数参数的值,那么可以加上const
防止其值的更改。
2. static关键字
2.1 static的使用场景
2.2 static函数强行调用非static的值
法1:传入实例化对象的地址
class A
{
public:
A(int x) : Ia(x) {}
static void test(A* a) // 传入实例化的地址,从这个指针访问非静态成员变量/函数
{
a->Ia += 1;
}
public:
int Ia;
};
int main()
{
A a(0);
std::cout << a.Ia << std::endl;
A::test(&a);
std::cout << a.Ia << std::endl;
}
法2:通过全局变量的对象访问
A g_a; // 创建全局变量
class A
{
public:
A(int x) : Ia(x) {}
static void test()
{
g_a->Ia += 1; // 直接调用全局变量的值
}
public:
int Ia;
};
法3:通过访问静态对象A,来访问A中的非静态成员变量/函数
class A
{
public:
A()
{
s_A = this;
}
static void test()
{
s_A->Ia += 1;
}
private:
static A* s_A;
int Ia;
};
法4:传入引用,直接传入对象进行更改
class A
{
public:
A(int x) : Ia(x) {}
static void test(A& a) // 传入对象的引用
{
a.Ia += 1;
}
public:
int Ia;
};
int main()
{
A a(1);
std::cout << a.Ia << std::endl;
a.test(a);
std::cout << a.Ia << std::endl;
}
3. virtual关键字
3.1 virtual的使用场景
4. 内存管理
4.1 new的原理
new关键字主要做了两步事情:
(1)调用operator new
函数为对象的创建分配内存,通过sizeof
来计算出内存的大小,传入函数的size_t
void *operator new(size_t) throw(bad_alloc); // 标准函数
void *operator new(size_t, const nothrow_t &) throw(); // 没有抛出异常的重载
void *operator new(size_t, void *) throw(); // placement
在operator new
中使用malloc
申请内存,若内存申请失败会抛出异常std::bad_alloc
。
(2)若成功分配内存,在其上调用类的构造函数。
而operator new[]
仅是在做上面两步事情的重复
new与malloc的区别:
(1)new会初始化对象,而malloc不会
(2)new会抛出异常,malloc只会返回nullptr