需具备的知识体系知识
1、编译链接
编译:C和C++都是按行编译,因此如果需要调用一个函数,如果在调用之前的代码里面没有定义或声明则会报编译错误,找不到
链接;主要是作用域和文件内外部链接属性相关的,这里就是要确保调用的时候能够找得到,编译和作用域的规则决定能否能够看到,链接是能够找到,而链接属性就会决定你是否能够找到。
2、C语言中的常识
1)static;主要是限制其修饰的在同一文件使用(具体可修改局部(还会修改存储域有栈到数据段)和全局(修改链接属性,由外部变成内部)),实践一下,static定义的只会执行一次
2)extern;全局变量,和定义的时候都可以省略extern,其作用就是告诉链接器,extern修饰的是由外部引入的,需要去有其他外部链接属性的里面找。
3)小作用域优先于大作用域;类似于局部变量定义相同与全局变量的名字,则在局部内会优先使用局部定义的,优先级高于全局的
3、引入C++中的namespace
1)命名空间的作用及用法
作用:对全局变量和函数等成员在一定范围内链接属性的更改和控制;意思就是打包的作用,将一些需要共同链接属性的打包到一起成一个命名空间,而想要调用里面的成员,那么就必须先调用到这个命名空间才能调用到里面的成员。从而通过命名空间名来控制链接属性,达到管理内部所有成员的链接属性。
//直接根据之前的c基础和编译作用域规则推导即可
#include <iostream>
using namespace std;
namespace Ns1
{
void f1()
{
cout << "1" << endl;
}
};
//using Ns1::f1;
//using namespace Ns1;
int main()
{
//f1();//如果没有前面的声明则会报错,因为作用域问题找不到
//因为定义在前则编译的时候能够找到(要先声明否则编译报错)
//链接的时候指明Ns1则没有问题
Ns1::f1();
//f1();//在前面声明using namespace Ns1;或者声明using Ns1::f1();
return 0;
}
2)同文件之间定义使用namespace
注意3点以及using的三种方法是不同概率
3)不同C文件之间如何定义和使用namespace
其关键解决调用其他文件中namespace成员时的编译链接问题。从而就到了就是如果跨文件声明namespace成员的问题。
//推导跨文件namespace要如何声明
//namespace Ns1;//报错说没有{}
//namespace Ns1{};//这个其实是再次定义了一个Ns1命名空间
namespace Ns1{void f1();};//C中学到,声明就是把定义去掉即可,这样可以调用到,应该是namespace本身就有外部链接属性
namespace Ns1{extern void f1();};//但是我们最好还是加上extern 表示这个函数从外部链接进来,
int main()
{
//f1();//同样先推导,直接这样些肯定找不到的,编译链接都不行
Ns1::f1();//这样可以尝试,同样报错找不到NS,那么因为在文件外,利用c中extern来声明
return 0;
}
/*
test2.cpp
#include <iostream>
using namespace std;
namespace Ns1
{
void f1()
{
cout << "1" << endl;
}
};
*/
注意的是跨文件声明的时候要挨个声明;未找到iostream的源码文件,不然截图展示,
iostream的源码文件安装在/usr/include/c++下,gcc的头文件在/usr/include下
4)默认命名空间;也叫全局命名空间,正规可以用::直接调用,省略也是可以的,冲突时仍然是小优先于大的原则
#include <iostream>
using namespace std;
namespace Ns1
{
void f1()
{
cout << "2" << endl;
}
}
using namespace Ns1;
//这样的外部其实就是默认空间或全局命名空间
void f1()
{
cout << "1" << endl;
}
int main()
{
f1();//可以直接省略调用,但是存在冲突时就会报错,因此调用命名空间中的最好加入命名空间的名字,前缀
//::f1();//也可以用正规的调用方法
return 0;
}
4)匿名命名空间;主要用于跨文件时,不让其他文件使用匿名空间中的元素,因为没有名字你也调用不到,类似于C中的static,限制了链接属性,让其他文件无法调用到
就如之前夸文件声明命名空间一致 ,namespace Ns1{extern void f1();};,如果我们把命名空间的名字省略,那么也就是声明不了,找不到,那么
5)嵌套命名空间;冲突时其实就是遵守小优先于大,调用就是按顺序写过来就行了
引入朱有鹏老师C++课程;
注意体会这种学习方法,核心是:
第一步明确问题,
第二步自我分析,
第三步实验验证,
总纲是形成自我知识体系,本质上站在和语言特性设计者一样的高度来看待和学习研究语言。