C++ 基础知识梳理

本文主要描述1:const修饰符,2:模版相关内容,3:指针和引用的区别,4:内联与预定义,5:虚表相关内容。

一:const修饰符
const修饰符可以修饰函数,函数参数,函数返回值,变量等。
(1)修饰函数 int function() const
const修饰函数表明在函数内不能修改对象数据成员且不能调用非const函数。因为在非const内部能修改数据成员,而const修饰的函数是不能改变的,因此是不能调用的。
(2)修饰函数参数 int function(const int& value)
防止传入的参数代表的内容在函数体内被改变,但仅对指针和引用有意义。如果是按值传递,传给参数的是实参的副本,即使改变形参,实参也不会受影响。
const修饰指针时,代表在函数体内不能修改该指针所指的内容,起到保护作用,const指针能接受非const和const指针,而非const指针只能接受非const指针。
const修饰引用时,按值传递时拷贝存在空间和时间的浪费,如果按引用传递能解决这个问题,但是存在安全隐患,这时候可以用const来保护。
(3)const修饰函数返回值
也是用来修饰返回的指针或引用,保证内容不被修改。归根结底是使得函数调用表达式不能作为左值。
int& get(); === get() = 2;
const int& get();

二:模版相关内容
模版是泛型编程的公式。我们可以用模版来定义函数和类。
函数模版
template ret-type func-name(parameter list)

inline T const& Max(T const& a, T const& b)
{
    return a < b ? b : a;
}
int I = 10, j = 20;  cout << Max(i, j)<<endl;
string a = "hello", b = "world"; cout<<Max(a,b)<<endl;

类模版
template class class-name{
.
.
.
}

> template<class T> class Stack{
>        public:
>        void pop();
>        private:
>        vector<T> elems; };
> 
> template <class T> void Stack<T>::pop() {
>        if (elems.empty()){
>               throw out_of_range("stack<>::pop(): empty stack");
>        }
>        elems.pop_back(); }

模版特化

> template <> void Stack<int>::pop() {
>        if (elems.empty()){
>               throw out_of_range("stack<int>::pop(): empty stack");
>        }
>        elems.pop_back(); }

模版特化分为全特化和偏特化,全特化是所有类型都指明,偏特化是指部分知名。调用的顺序是全特化类>偏特化类>主版本模版类。

三:指针和引用的区别
(1)引用
int m;
int &n = m;
n相当于是m的别称,对n的操作就是对m的操作,n就是m它自己。
引用的规则
1)引用被创建的同时必须被初始化(指针则可以在任何地方初始化)
2)不能有NULL引用,引用必须与合法的存储单元关联(指针可以为NULL)
3)一旦引用呗初始化,则不能改变引用关系(指针可以随时改变所指的对象)
引用的主要功能是传递函数的参数和返回值。
C++语言中参数和返回值的传递方式有三种,值传递,指针传递和引用传递。
程序为指针变量分配内存区域,而引用不分配内存区域。
指针可以被重新赋值以指向另一个不同的对象,但引用总是窒息那个初始化时被指定的对象,以后不能改变。
sizeof(引用)得到所指向内容的大小,sizeof(指针)得到指针本身的大小。

四:内联和宏定义
#define Max(a,b) ((a)>(b)?(a)>(b))
inline int Max(int a, int b) {return a>b?a:b;}

内联的好处:
(1)内联能调试
(2)可进行类型安全检查或自动类型转换。
(3)可访问成员变量。
(4)内联函数提高了效率(省去调用汇编代码,call和ret等)
如果代码长,使用内联会导致内存消耗代价比较大,如果内联代码内出现循环,那么执行函数体内的代码的时间要比函数调用的开销大。

五:虚表相关内容
在C++语言中,每个有虚函数的类或者虚继承的子类,编译器都会为它生成一个虚拟函数表(简称:虚表),表中的每一个元素都指向一个虚函数的地址。(注意:虚表是从属于类的)
此外,编译器会为包含虚函数的类加上一个成员变量,是一个指向该虚函数表的指针(常被称为vptr),每一个由此类别派生出来的类,都有这么一个vptr。虚表指针是从属于对象的。也就是说,如果一个类含有虚表,则该类的所有对象都会含有一个虚表指针,并且该虚表指针指向同一个虚表。
虚表的内容是依据类中的虚函数声明次序–填入函数指针。派生类别会继承基础类别的虚表(以及所有其他可以继承的成员),当我们在派生类中改写虚函数时,虚表就受了影响;表中的元素所指的函数地址将不再是基类的函数地址,而是派生类的函数地址。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值