微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

面向对象的编程问题:按值传递与按引用传递

如何解决面向对象的编程问题:按值传递与按引用传递

以下是我针对模拟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 举报,一经查实,本站将立刻删除。