1.接口和抽象类的区别
- 接口是对动作的抽象;抽象类是对根源的抽象。
- 抽象类表示这个对象是什么;接口表示的是,这个对象能做真么。
- 一个类一般只能继承一个抽象类;但是可以实现多个接口。
2.sizeof
class A
{
};
class B
{
public:
B(){}
};
class C
{
public:
virtual void fun(){};
};
class D
{
public:
virtual void fun() = 0;
};
- sizeof(A) = 1 :因为我们声明类类型的实例的时候,必须在内存中占有一定的空间,否则无法使用这些实例。
- sizeof(B) = 1 :因为调用构造函数与析构函数只用知道函数地址即可。
- sizeof(C) = 4 :虚函数需要一个指向虚表的指针,而一个指针在32位机器上是4字节,在64为机器上是8字节。
- sizeof(D) = 4 :同上
3.main函数执行以前及以后,分别还会执行什么。
1)执行之前:
- 设置栈指针
- 初始化static静态与全局变量,即data段的内容
- 将未初始化的全局变量,static变量赋值:数值型赋值为0,bool赋值为false,指针为NULL,即bss段的内容
- 将main函数的参数,argc, argv传递给main函数。
2)执行之后:
- 全局对象的析构函数
- 在main函数中用ateixt()注册的终止处理程序。
4.malloc与new的区别
1)new是c++中的操作符;malloc是c中的一个函数
2)new不只会分配内存,而且会调用类的构造函数,同理delete会调用类的析构函数;而malloc则只是分配内存,不会进行初始化类成员的工作,同样free也不会调用析构函数。
3)不要用malloc/free来完成动态对象的内存管理,因为他们并没有调用构造/析构函数。
4)如果用free释放new 出来的对象,这个对象有可能因为无法执行析构函数而导致程序出错。如果用delete释放malloc申请的动态内存,原则上是不会错的,但是容易引起误会。
一篇实现malloc的文章
new与malloc的区别,以及内存分配浅析
new的注意一点:
int *ia = new int; //ia所指向的数值是未知的
int *ib = new int(); //ib所指向的数值是0
5.c++ 线程安全的单例模式
#include <thread>
#include <mutex>
class Lock
{
private:
std::mutex *cs; //临界资源
public:
Lock(std::mutex *mt):cs(mt)
{
cs->lock();
}
~Lock()
{
cs->unlock();
}
};
class single
{
private:
static single *pSingle;
static std::mutex cs; //临界资源
class Garbo
{
public:
~Garbo()
{
if(single::pSingle)
delete single::pSingle;
}
};
static Garbo garbo;
public:
static single *Instance()
};
single *single::pSingle = nullptr;
single * single::Instance()
{
if(pSingle == nullptr)
{
Lock lock(&cs); //这里声明了一个Lock类型的局部变量,这样
//在退出他的作用域之后就可以调用他的析构
//函数来对cs进行unlock;
if(pSingle == nullptr)
{
pSingle = new single();
return pSingle;
}
}
return pSingle;
}
6.static变量
static变量分为静态的全局变量与静态的局部变量。
他们之间的区别在静态的全局变量是一个全局的变量,可以被其他函数访问。而静态的局部变量只是一个局部变量,不能被其他函数访问。
第二:静态全局变量是在main函数之前被初始化的。而静态的局部变量是在执行到这个函数时才被初始化。
但是他们都存储在bss段或者data段。
常量存储区
char *str1 = "ABCD";
char *str2 = "ABCD";
/* 这里str1 == str2,因为ABCD存储在常量存储区,str1与str2都指向这一块区域。 */