整理代码的时候需要把用到的模型文件都放到工程目录下, 但自己程序中使用的读取模型的函数都需要绝对路径, 因此需要先有相对路径转绝对路径的操作.
参考材料
1. C++跨文件共享全局变量
2. C语言与C++中static,extern的用法及区别总结
首先利用getcwd函数获取当前工程的绝对路径,
#include <direct.h>
char *buffer;
//也可以将buffer作为输出参数
if ((buffer = getcwd(NULL, 0)) == NULL)
{
perror("getcwd error");
}
else
{
std::string input(buffer);
pathChange(input+"\\..\\..\\");
free(buffer);
}
因为自己清楚model文件夹放在外边, 所有可以看到上面的代码含有”\\..\\..\\”, pathChange函数返回当前的绝对路径经”\\..\\..\\”处理后的结果,
void pathChange(string input) {
vector<string> inputpath, outputpath;
string tmp;
for (int i = 0; i < input.size(); i++) { //将input字符串按‘/’分开存储到inputpath
if (input[i] != '\\') { //向量中。 注意:第一个为空字符串!
tmp += input[i];
}
else {
inputpath.push_back(tmp);
tmp.clear();
}
}
while (!inputpath.empty()) { //判断vector最后一个数据是否为“..”,若
if (inputpath.back() != "..") { //是,则连续2次删除尾数据,若否,则将尾数
tmp = inputpath.back(); //据存到outputpath中,并删除inputpath中的
outputpath.push_back(tmp); //尾数据。
inputpath.pop_back();
}
else {
int pop_num = 0;
int end = inputpath.size() - 1;
while (inputpath[end] == "..") {
pop_num += 2;
--end;
}
for (int i = 0; i < pop_num; ++i) inputpath.pop_back();
}
}
projectPath = "";
for (auto iter = outputpath.rbegin(); iter != outputpath.rend(); iter++) projectPath += (*iter) + "\\";
}
值得注意的是, 一开始我的pathChange的返回类型是string, 然鹅string对象一般不能做返回值的, 在跨模块调用时候会出问题, 直接返回string对象一般会是空, 汗…… 因为string里面的构造函数在堆空间动态申请了内存, 不属于栈变量, 函数结束时会调用string的构造函数, 析构函数里释放了在堆空间申请的内存.
还有需要注意的一点是projectPath是另外一个文件中定义的变量, 貌似是第一次使用extern关键字=。= 稍稍记录一下extern和static的用法.
下面的小栗子涉及到三个文件test.h, test.cpp, main.cpp.
// test.h #ifndef TEST_H #define TEST_H #include <iostream> #include <string> #include <vector> extern int global_v; void modify(); void print(); #endif
// test.cpp
#include "test.h"
using namespace std;
int global_v = 1;
void modify()
{
global_v++;
cout << "in test, value increases to " << global_v << endl;
}
void print()
{
cout << "in test, value is " << global_v << endl;
}
// main.cpp
#include "test.h"
using namespace std;
int main()
{
cout << "in main function, initial global value is " << global_v << endl;
modify();
print();
return 0;
}
static
当我们同时编译多个文件时, 所有未加static前缀的全局变量和函数都具有全局可见性. static可以用作函数和变量的前缀, 对于函数来讲,static的作用仅限于隐藏. 利用这一特性可以在不同的文件中定义同名函数和同名变量, 而不必担心命名冲突.
extern
extern则是告诉编译器这个变量或函数在其他文档里已被定义了. 另外用法是当C和C++混合编程时假如c++调用的是c源文档定义的函数或变量, 那么要加extern来告诉编译器用c方式命名函数:
extern "C" //在c++文档里调用c文档中的变量
{
int j;
void callme();
}
int main()
{
callme();
}
因此, static的设计法则是:
A. 若全局变量仅在单个C文档中访问, 则能够将这个变量修改为静态全局变量, 以降低模块间的耦合度;
B. 若全局变量仅由单个函数访问, 则能够将这个变量改为该函数的静态局部变量, 以降低模块间的耦合度;
C. 设计和使用访问动态全局变量、静态全局变量、静态局部变量的函数时, 需要考虑重入问题.