You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++中如何将对象作为函数参数?自定义栈类调用疑问

嘿,我来帮你搞定这两件事——先实现你需要的模板栈类,再给你讲清楚C++里对象作为函数参数传递的几种方式,包你明白~

1. 实现模板Stack类

首先咱们来写符合你要求的Stack模板类,包含栈的核心操作:压栈、弹栈、取栈顶、判断空这些。我用vector作为底层存储,因为它的push_back和pop_back效率很高,实现起来也简单:

#include <iostream>
#include <tuple>
#include <vector>
#include <stdexcept> // 用于抛出越界异常

template<typename T>
class Stack {
private:
    std::vector<T> elements; // 用vector存栈元素

public:
    // 默认构造、析构函数,编译器自动生成就行
    Stack() = default;
    ~Stack() = default;

    // 压栈操作,和你用的Push_back名字保持一致
    void Push_back(const T& item) {
        elements.push_back(item);
    }

    // 重载一个支持移动语义的版本,优化性能(可选但实用)
    void Push_back(T&& item) {
        elements.push_back(std::move(item));
    }

    // 弹栈操作,栈空时给个提示
    void Pop() {
        if (!IsEmpty()) {
            elements.pop_back();
        } else {
            std::cerr << "栈是空的,没法弹栈!" << std::endl;
        }
    }

    // 获取栈顶元素,栈空时抛出异常(比直接崩溃友好)
    T& Top() {
        if (!IsEmpty()) {
            return elements.back();
        } else {
            throw std::out_of_range("栈是空的,没有栈顶元素!");
        }
    }

    // 重载const版本的Top,方便给const对象用
    const T& Top() const {
        if (!IsEmpty()) {
            return elements.back();
        } else {
            throw std::out_of_range("栈是空的,没有栈顶元素!");
        }
    }

    // 判断栈是否为空
    bool IsEmpty() const {
        return elements.empty();
    }

    // 获取栈的大小
    size_t Size() const {
        return elements.size();
    }
};
2. C++中对象作为函数参数的传递方式

C++里传递对象主要有三种方式,咱们结合你的Stack对象逐一说明:

2.1 值传递

简单说就是把对象拷贝一份传给函数,函数里操作的是这个副本,完全不会影响原对象。比如:

void read_command(Stack<std::tuple<std::string, int, int, int, int>> stack) {
    // 这里的stack是main里S的拷贝,改它和原S没关系
    stack.Push_back(std::make_tuple("test", 5,6,7,8));
}

⚠️ 缺点:如果栈里存了大量元素,拷贝的开销会很大,效率很低,一般除非你特意要操作副本,否则别用这种方式。

2.2 引用传递

这是最常用的方式——传递对象的引用,函数里直接操作原对象本身。又分两种:

  • 非const引用:允许修改原对象,适合你需要在函数里操作栈(比如压栈、弹栈)的场景:
    void read_command(Stack<std::tuple<std::string, int, int, int, int>>& stack) {
        // 这里的操作会直接作用到main里的S
        stack.Push_back(std::make_tuple("hello", 10,20,30,40));
        std::cout << std::get<0>(stack.Top()) << " ";
    }
    
  • const引用:如果函数只需要读取栈的内容,不需要修改,就用const引用,既安全又避免拷贝:
    void print_stack(const Stack<std::tuple<std::string, int, int, int, int>>& stack) {
        // 这里只能调用const成员函数,比如Top()的const版本、IsEmpty()
        if (!stack.IsEmpty()) {
            std::cout << std::get<0>(stack.Top()) << std::endl;
        }
    }
    

✅ 优点:没有拷贝开销,效率高,还能直接操作原对象(非const引用),是日常开发的首选。

2.3 指针传递

传递对象的指针,本质和引用类似,但语法上要用到->访问成员,还要注意空指针的问题:

void read_command(Stack<std::tuple<std::string, int, int, int, int>>* stack) {
    if (stack != nullptr) { // 先判断指针是不是空的,避免崩溃
        stack->Push_back(std::make_tuple("test", 5,6,7,8));
    }
}

// 调用的时候要传对象的地址
read_command(&S);

这种方式现在用得不如引用多,因为引用更安全(不会有空引用的问题,只要你传递的是合法对象)。

完整可运行示例

把上面的代码整合起来,你可以直接运行:

#include <iostream>
#include <tuple>
#include <vector>
#include <stdexcept>

template<typename T>
class Stack {
private:
    std::vector<T> elements;

public:
    Stack() = default;
    ~Stack() = default;

    void Push_back(const T& item) {
        elements.push_back(item);
    }

    void Push_back(T&& item) {
        elements.push_back(std::move(item));
    }

    void Pop() {
        if (!IsEmpty()) {
            elements.pop_back();
        } else {
            std::cerr << "栈是空的,没法弹栈!" << std::endl;
        }
    }

    T& Top() {
        if (!IsEmpty()) {
            return elements.back();
        } else {
            throw std::out_of_range("栈是空的,没有栈顶元素!");
        }
    }

    const T& Top() const {
        if (!IsEmpty()) {
            return elements.back();
        } else {
            throw std::out_of_range("栈是空的,没有栈顶元素!");
        }
    }

    bool IsEmpty() const {
        return elements.empty();
    }

    size_t Size() const {
        return elements.size();
    }
};

void read_command(Stack<std::tuple<std::string, int, int, int, int>>& stack) {
    stack.Push_back(std::make_tuple("hello", 10, 20, 30, 40));
    std::cout << std::get<0>(stack.Top()) << " ";
}

int main() {
    Stack<std::tuple<std::string, int, int, int, int>> S;
    S.Push_back(std::make_tuple("cabs", 1, 2, 3, 4));
    std::cout << std::get<0>(S.Top()) << " ";
    read_command(S);
    std::cout << std::endl;
    return 0;
}

运行后会输出:cabs hello ,完全符合你的预期。

内容的提问来源于stack exchange,提问作者M.Ritz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 07:50:45