C++中的持续性和链接性
一.静态持续性,外部链接性
1.单定义规则
定义声明:分配储存空间
引用声明:不分配储存空间,使用关键字extern;
//file01.cpp extern int cats=20; int dogs=22; int fleas; //file02.cpp extern int cats; extern int dogs; //file98.cpp extern int dogs; extern int cats; extern int fleas;
二。静态持续性,内部连接性
在加上关键字static后,该变量为内部链接性,在其它文件中定义不会冲突。
若在两个文件中使用一个变量名,则会报错。
三,静态持续性,无链接性
const int ArSize = 10; void strcount(const char* str); int main() { char input[ArSize]; char next; cout << "Enter a line\n"; cin.get(input, ArSize); while (cin) //cin.get(char*,int)读取空行会导致false { cin.get(next); while (next != '\n') { cin.get(next); } strcount(input); cout << "Enter next line (empty line to quit):\n"; cin.get(input, ArSize); } } void strcount(const char* str) { static int total = 0; int count = 0; cout << "\"" << str << "\" contains"; while (*str++) { count++; } total += count; cout << count << " characters \n"; cout << total << " characters total\n"; }
代码运行结果:
Enter a line nice pants "nice pant" contains9 characters 9 characters total Enter next line (empty line to quit): thanks "thanks" contains6 characters 15 characters total Enter next line (empty line to quit): parting is such sweet sorrow "parting i" contains9 characters 24 characters total Enter next line (empty line to quit): ok "ok" contains2 characters 26 characters total Enter next line (empty line to quit):
count被重置,而total不会
总的来说,当static被用于全局时,表现为内部链接性,用于局部时,表现为储存持续性。
四.const
const全局变量链接性是内部的,这样使得在头文件中定义的const可以在多个源文件中可用,而不会出现重复定义的报错,并且内部链接性以为着该变量是文件私有的,不会被多个文件间共享。
如果此时希望const修饰的变量的链接性是外部的,可以用extern来覆盖内部链接性。
五。函数和链接性
默认情况下,函数的链接性是外部的,储存性是静态的,可以在文件之间共享,使用extern引用声明,不过这是可选的。
也可以使用static使其只能在一个文件内使用,并且会覆盖外部定义。
内联函数不受这种约束,允许将内联函数的定义放在头文件中。
C++将在哪里去查找函数?
如果原型指出该函数是静态的,则只在该文件中查找,否则编译器将在其他文件中查找,若找不到,会到库文件中查找,编译器会优先选择自己定义的版本。
六。储存方案和动态分配
1.使用new初始化
int *pi =new int(6); double *pd= new double (99.99); struct where{double x; double y; double z;}; where * one = new where {2.5,5.3,7.2}; //c++11 inbt *ar = new int[4] {2,4,6,8}; //c++11 //在c++11中,可以用列表初始化单值变量 int *pin =new int {}; double *pdo = new double{99.99};
2.当new初始化失败时,早期时返回空指针,当现在返回异常std::bad_alloc.
3.new:运算符,函数和替换函数
//函数原型 void *operator new(std::size_t); void *operator[] new(std::size_t); void delete new(void*); void delete[] new(void*); //使用时 int * pi=new int; //int * pi=new(sizeof(int)); int *pa =new int[40]; // int *pa=new(40*sizeof(int)); delete pi;//delete(pi);
4.定位new运算符
#include<new> using namespace std; struct chaff { char dross[20]; int slag; }; char buffer1[50]; char buffer2[500]; int main() { chaff* p1, *p2; int* p3, * p4; //the normal means p1 = new chaff; p3 = new int[20]; //the placement means p2 = new(buffer1) chaff; p4 = new(buffer2) int[20]; }
#include<iostream> #include<new> using namespace std; const int BUF = 512; const int N = 5; char buf[BUF]; int main() { double* pd1, * pd2; pd1 = new double[N]; pd2 = new (buf) double[N]; cout << "Calling new and placement new first:" << endl; for (int i = 0; i < N; i++) { pd1[i] = pd2[i] = 1000 + 20.0 * i; } cout << "Memory address:\n" << "heap:" << pd1 << "static:" << (void*)buf << endl; for (int i = 0; i < N; i++) { cout << pd1[i] << " at " << &pd1[i] << endl; cout << pd2[i] << " at " << &pd2[i] << endl; } cout << "Calling new and placement new a second time" << endl; double* pd3, * pd4; pd3 = new double[N]; pd4 = new (buf) double[N]; for (int i = 0; i < N; i++) { pd3[i] = pd4[i] = 1000 + 40.0 * i; } cout << "Memory comments: " << endl; for (int i = 0; i < N; i++) { cout << pd3[i] << " at " << &pd3[i] << endl; cout << pd4[i] << " at " << &pd4[i] << endl; } cout << "Calling new and placement new a third time" << endl; delete[] pd1; pd1 = new double[N]; pd2 = new (buf+N*sizeof(double)) double[N]; for (int i = 0; i < N; i++) { pd2[i] = pd1[i] = 1000 +60.0 * i; } cout << "Memory comments: " << endl; for (int i = 0; i < N; i++) { cout << pd1[i] << " at " << &pd1[i] << endl; cout << pd2[i] << " at " << &pd2[i] << endl; } }
运行结果:
Calling new and placement new first: Memory address: heap:000001E0566396F0static:00007FF6910E06D0 1000 at 000001E0566396F0 1000 at 00007FF6910E06D0 1020 at 000001E0566396F8 1020 at 00007FF6910E06D8 1040 at 000001E056639700 1040 at 00007FF6910E06E0 1060 at 000001E056639708 1060 at 00007FF6910E06E8 1080 at 000001E056639710 1080 at 00007FF6910E06F0 Calling new and placement new a second time Memory comments: 1000 at 000001E056643C40 1000 at 00007FF6910E06D0 1040 at 000001E056643C48 1040 at 00007FF6910E06D8 1080 at 000001E056643C50 1080 at 00007FF6910E06E0 1120 at 000001E056643C58 1120 at 00007FF6910E06E8 1160 at 000001E056643C60 1160 at 00007FF6910E06F0 Calling new and placement new a third time Memory comments: 1000 at 000001E056643700 1000 at 00007FF6910E06F8 1060 at 000001E056643708 1060 at 00007FF6910E0700 1120 at 000001E056643710 1120 at 00007FF6910E0708 1180 at 000001E056643718 1180 at 00007FF6910E0710 1240 at 000001E056643720 1240 at 00007FF6910E0718
其中buf不可以使用delete释放,buffer在delete的管辖区之外,这进一步验证了new和delete的配套使用。

浙公网安备 33010602011771号