如何解决面向对象的编程问题:按值传递与按引用传递
以下是我针对模拟bash终端的程序的方法。
class Shell
{
public:
string currentDir;
vector<string> cmdHistory;
vector<pid_t> pidHistory;
public:
Shell(string dir)
{
this->currentDir = dir;
this->cmdHistory.clear();
this->pidHistory.clear();
};
// Get the current directory
string getDir()
{
return this->currentDir;
}
void setDir(string dir)
{
this->currentDir = dir;
}
void appendDir(string dir)
{
this->currentDir.append(dir);
}
void recordCmd (string record)
{
cmdHistory.push_back(record);
}
void recordPID(pid_t record)
{
this->pidHistory.push_back(record);
}
void printCmdHistory()
{
int size = cmdHistory.size();
if (size == 0)
return;
for (int i = 0; i < size; i++)
{
cout << cmdHistory[i] << "\n";
}
}
void clearHistory()
{
cmdHistory.clear();
}
void clearPIDHistory()
{
pidHistory.clear();
}
int getPIDsize()
{
return this->pidHistory.size();
}
pid_t getCurrentPID()
{
return this->pidHistory.at(pidHistory.size() - 1);
}
pid_t getAtPID(int i)
{
return pidHistory.at(i);
}
};
这是我的对象类型Shell。然后,我在无限循环中继续在main中调用一种新的Shell对象,并执行以下操作:
Shell newShell(currentDir);
do
{
cout << "#";
getline(cin,inputBuffer);
newShell = processLine(newShell,inputBuffer);
cout << endl;
}while(inputBuffer.compare("byebye") != 0);
类似地,我在函数processLine()中执行相同的操作:
// #background:
else if (args[0].compare("background") == 0)
{
if (args.size() > 1)
{
// CASE I: Full path
if (args[1][0] == '/')
{
// There's a parameter
if (args.size() > 2)
{
currentShell = backgroundProgramHelper(currentShell,args,true);
}
else
{
currentShell = backgroundProgramHelper(currentShell,false);
}
}
// CASE II: Relative path
else
{
// Append program to current directory address
args[1] = currentShell.getDir() + "/" + (args[1]);
// There's a parameter
if (args.size() > 2)
{
currentShell = backgroundProgramHelper(currentShell,false);
}
}
}
backgroundProgramHelper()函数执行以下操作:
Shell backgroundProgramHelper(Shell currentShell,vector<string> args,bool flag)
{
if (flag)
{
// Get rid of '-'
string flag = args[2];
string delimeter = "-";
size_t pos = flag.find(delimeter);
string token = flag.substr(0,pos);
args[2] = flag.erase(0,pos + delimeter.length());
// DMA a char * for the amount of parameters.
// I made the assumption based on the example given
// that the total amount of parameters passed would 2
char * arguments[4];
arguments[0] = (char*)args[1].c_str(); // program
arguments[1] = (char*)args[2].c_str(); // flag
arguments[2] = (char*)args[3].c_str(); // flag
arguments[3] = NULL;
pid_t pid = fork();
// ERROR
if (pid == -1)
perror("ERROR: Failed to fork");
// Child
if (pid == 0)
{
cout << "child: " << pid << endl;
if (execvp (arguments[0],arguments) == -1)
{
perror("exec");
}
}
// Parent
if (pid > 0)
{
wait(0);
currentShell.recordPID(pid);
cout << "\nparent: " << pid << endl;
}
}
else
{
char * arguments[2];
arguments[0] = (char*)args[1].c_str(); // program
arguments[1] = NULL;
pid_t pid = fork();
// ERROR
if (pid == -1)
perror("ERROR: Failed to fork");
// Child
if (pid == 0)
{
cout << "child: " << pid << endl;
if (execvp (arguments[0],arguments) == -1)
{
perror("exec");
}
}
// Parent
if (pid > 0)
{
wait(0);
currentShell.recordPID(pid);
cout << "\nparent: " << pid << endl;
}
}
return currentShell;
}
它采用currentSHell,然后使用已运行的任何程序更新PID的历史记录。问题是,如果我将backgroundProgramHelper类型设置为void并且不返回Shell类型变量来更新我传递的变量,那么我的main对象不会随着程序运行的PID历史记录而更新。我认为这是按值传递和按引用传递的基本问题,但是同样,我不确定为什么我必须执行currentSHell = backgroundProgramHelper(Shell currentShell,vector args,bool flag)才能获得我的PID历史记录以进行更新。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。