C++知识点点点点点(3)

  • 字节对齐

计算机中内存大小的基本单位是字节(byte),理论上来讲,可以从任意地址访问某种基本数据类型,但是实际上,计算机并非逐字节大小读写内存,而是以2,4,或8的倍数的字节块来读写内存,如此一来就会对基本数据类型的合法地址作出一些限制,即它的地址必须是2,4或8的倍数。那么就要求各种数据类型按照一定的规则在空间上排列,这就是对齐。

存储首地址为数据类型的整数倍;占用总存储空间最大数据类型的整数倍。。。

*参考:https://zhuanlan.zhihu.com/p/44625744https://www.cnblogs.com/zjc0202/p/4409939.html

 

  • C++多态性

编译时的多态性:函数/操作符的重载 >>静态联编

运行时的多态性:通过派生类和虚函数实现 >>动态联编

 

  • 虚函数、纯虚函数、与虚函数表

虚函数是实现多态的机制,通过基类访问派生类定义的函数。多态性使得程序调用的函数是在运行时动态确定的,而不是在编译时静态确定的。使用一个基类类型的指针或者引用,来指向子类对象,进而调用由子类复写的个性化的虚函数。

虚函数:virtual void func(),继承类中可以复写可以不复写。

纯虚函数:virtual void func()=0,此时该类成为抽象类,不能够创建实例,继承类中必须对纯虚函数进行复写。

虚函数表:编译器处理虚函数时,给每个对象添加一个隐藏成员,隐藏成员中保存了一个指向函数地址数组的指针,这种数组称为虚函数表(vbtl)。例如:基类对象包含一个指针,该指针指向基类中所有虚函数的地址表;派生类对象将包含一个指向独立地址地址表的指针。


class A  
{  
public:  
    virtual void foo()  
    {  
        cout<<"A::foo() is called"<<endl;  
    }  
};  
class B:public A  
{  
public:  
    void foo()  
    {  
        cout<<"B::foo() is called"<<endl;  
    }  
};  
int main(void)  
{  
    A *a = new B();  
    a->foo();   // 在这里,a虽然是指向A的指针,但是被调用的函数(foo)却是B的!  
    return 0;  
}

*参考:https://www.zhihu.com/question/23971699/answer/69592611

 

  • static与const

static变量:在类中声明一个static变量,类似全局变量,在类和它的对象中都可以使用;只分配一次内存,类外存储,存放在数据区,(auto)变量在栈区;必须进行初始化,只能在类外初始化,默认为0。

static函数:用于管理类中的static变量,只能访问类中的静态数据成员;不能传入this指针(属于类,但不属于对象,对象才有this指针); staitc 修饰成员函数,仅出现在声明处,如果在类外定义,不可出现在定义处。

const常量:定义的同时要初始化,之后不能再去赋值,只能使用。

const函数:const修饰函数,const关键字放在声明之后,实现之前;const 修饰函数不能修改类内的数据成员变量;const 修饰函数只能调用 const 函数;const 修饰的全局函数在定义和声明处都需要 const 修饰符。

const对象:只能访问类中的const成员函数。

*参考:https://www.cnblogs.com/retry/p/9509403.html

 

  • return *this与return this

this本身是一个指针!this本身是一个指针!this本身是一个指针!!!this--当前对象的指针

return this:返回当前对象的指针

return *this:返回当前对象的克隆或者本身(若返回类型为A, 则是克隆, 若返回类型为A&, 则是本身 )

参考:https://blog.csdn.net/stpeace/article/details/22220777

(跑了一下参考连接的一段代码,似乎在clion中不支持临时对象取地址的操作)

 

  • class访问修饰符

(class默认private,struct默认public)

public:在程序中类的外部是可访问的,可以不使用任何成员函数来设置和获取公有变量的值

private:变量或函数在类的外部是不可访问的,只有类中的函数和友元函数可以访问私有成员

protected:变量或函数与私有成员类似,但保护成员在派生类(即子类)中是可访问的

(在public\protected\private方式继承时,访问权限为最低的)

 

  • 移动语义与右值引用

移动语义:避免移动原始数据和反复的复制过程,只修改记录。类似于换个人来接管之前的数据,而数据不需要变动。

右值引用:实现移动语义的方式,根据引用方式的不同,告诉编译器什么时候使用拷贝,什么时候不需要。即根据引用方式的不同,选择执行复制构造函数还是移动构造函数。(右值:字面值常量和表达式)

以C++ Primer Plus的说明为例:

//复制构造与移动构造(Useless为定义的class)
Useless two=one;//复制构造
Useless four(one+three);//移动构造

Useless::Useless(Useless&& f):n(f.n) //移动构造
{
    pc=f.pc;//获取右值引用的指针
    f.pc=nullptr;//设置原来的指针为空指针,因为不能对一个地址同时delete两次,可以delete空指针
    f.n=0;
}


Useless& Useless::operator=(Useless&& f)//移动赋值
{
    if(this==&f) return *this;
    delete [] pc;
    n=f.n;
    pc=f.pc;
    f.n=0;
    f.pc=nullptr;
    return *this;
}

在C++11之前没有右值引用、移动构造,对于Useless four(one+three),编译器的处理过程如下:

*移动构造/赋值的参数不能设置为const,因为移动语义修改了源对对象。

 

  • if(this==&f) return *this

判断传入的引用参数和当前的实例是否是同一个。同一个,则直接返回,不进行赋值操作。如果不进行判断,当是同一个实例的时候,进行赋值之后,因为是进行的引用,释放其中一个内存,另外一个也同时被释放。

 

  • delete与delete[]
delete释放new的简单对象的内存;delete[]释放new的对象(class)数组的内存。
int* a=new int[10];
delete a;
delete [] a;  //两者等价

A* a=new A[10];
delete a; //只释放a[0]
delete [] a;//释放a指向的所有内存,调用每个对象的析构函数进行释放

*参考:https://www.cnblogs.com/wkfvawl/p/10846851.html

 

  • decltype()

C++11引入,返回操作数的数据类型。

 

  • std::ref()与std::reference_wrapper

在做多线程过程中,遇到如下的函数:

std::thread(&GroundClassifier::SortPointCloudThread,this,std::ref(pointcloud));

pointcloud作为引用传递,加了一个std::ref()。查阅资料,发现C++对std::bind()和std::thread()的参数传递有一点特殊的要求,这两个是对参数的直接拷贝而不是引用,模板参数为按值传递时,正常;但如果想要使用引用,必须加上std::ref()。

std::ref()返回一个std::reference_wrapper的对象,而reference_wrapper字面意思是参考包装,即对本来按值传递的参数进行一次包装,利用模板函数的自动推倒类型,将参数隐式转换为引用,但reference_wrapper本身并不能用作&类型。总的来说就是实现对参数的模拟引用。

当然,上面说到了需要利用模板的类型自动推倒,对于非模板函数,就不能这样使用了。

*参考:https://blog.csdn.net/u014645632/article/details/78966340https://www.jianshu.com/p/277675675593

 

  • std::bind()

通俗的说,将函数和其参数进行绑定,生成新的函数。在调用新的函数时,便会将参数传给原来的函数。

*参考:https://www.jianshu.com/p/07eae70771fb

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值