Effective C++ 条款20_宁以 pass-by-reference-to-const 替换 pass-by-value_不止于此

Prefer pass-by-reference-to-const to pass-by-value

缺省情况下 C++ 以 by value 方式(一个继承自 C 的方式)传递对象至(或来自)函数。
但以值传递会由对象的 copy 构造函数产出,这可能使得 pass-by-value 成为昂贵的(费时的)操作。
那么我们有什么方法可以避免那些不必要的行为呢?那就是用 pass-by-reference-to-const 替换 pass-by-value。

class Student{...};
bool isValid(Student s);		// pass-by-value   费时
bool isValid(const Student& s);	// pass-by-reference-to-const  快且可避免切割问题

切割问题:
就是说如果传递一个 derived class 的对象,也许只有 base class 的属性被拷贝了,也就导致了不明确行为。但以 pass-by-reference-to-const 传递就不会出现这种问题,因为不会去调用 copy 构造函数。

如果窥视 C++ 编译器的底层,你会发现,references 往往以指针实现出来,因此 pass-by-reference 通常意味着传递的是指针。
请记住:

  • 尽量以 pass-by-reference-to-const 替换 pass-by-value。前者通常比较高效,可以避免切割问题。
  • 以上规则并不适用于内置类型,以及 STL 的迭代器和函数对象。对它们而言,pass-by-value 往往比较适当。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,你的问题是关于分支限界法实现最优装载问题的C++代码。 首先,需要明确最优装载问题的定义:给定一些物品和一个容量为C的箱子,每个物品有各自的重量和价值,要求在不超过箱子容量的情况下,将价值最大化的物品装入箱子中。 接下来,我们可以使用分支限界法来解决这个问题。具体思路如下: 1. 将物品按照单位重量的价值从大到小排序。 2. 定义一个节点,包含当前所选物品的重量、价值、剩余容量和已选择的物品。 3. 对于每个节点,计算其可行的子节点。如果子节点的重量小于箱子容量,则将子节点加入队列中。 4. 对于每个可行的子节点,计算其上界(即该节点之后能够获得的最大价值),并更新最优解。 5. 选择上界最大的节点,将其扩展成子节点,重复步骤3-5,直到队列为空。 下面是实现最优装载问题的C++代码,其中使用了一个优先队列来存储节点,并按照上界从大到小排序: ```c++ #include <iostream> #include <queue> #include <vector> #include <algorithm> using namespace std; struct Node { int weight; // 已选物品的总重量 int value; // 已选物品的总价值 int capacity; // 剩余容量 vector<int> items; // 已选择的物品编号 double upper_bound; // 上界 bool operator<(const Node& other) const { return upper_bound < other.upper_bound; } }; double get_upper_bound(const Node& node, const vector<int>& weights, const vector<int>& values, int n) { double ub = node.value; int j = node.items.size(); int total_weight = node.weight; while (j < n && total_weight + weights[j] <= node.capacity) { ub += values[j]; total_weight += weights[j]; j++; } if (j < n) { ub += (node.capacity - total_weight) * (double)values[j] / weights[j]; } return ub; } int best_value(const vector<int>& weights, const vector<int>& values, int capacity) { int n = weights.size(); vector<int> indices(n); for (int i = 0; i < n; i++) { indices[i] = i; } sort(indices.begin(), indices.end(), [&](int a, int b) { return (double)values[a] / weights[a] > (double)values[b] / weights[b]; }); priority_queue<Node> q; Node root{ 0, 0, capacity, {}, get_upper_bound({ 0, 0, capacity, {}, 0 }, weights, values, n) }; q.push(root); int best = 0; while (!q.empty()) { Node node = q.top(); q.pop(); if (node.upper_bound < best) { break; } if (node.value > best) { best = node.value; } int i = node.items.empty() ? 0 : node.items.back() + 1; if (i < n) { Node left = node; left.weight += weights[indices[i]]; left.value += values[indices[i]]; left.capacity -= weights[indices[i]]; left.items.push_back(indices[i]); left.upper_bound = get_upper_bound(left, weights, values, n); if (left.upper_bound >= best) { q.push(left); } Node right = node; right.items.push_back(indices[i]); right.upper_bound = get_upper_bound(right, weights, values, n); if (right.upper_bound >= best) { q.push(right); } } } return best; } int main() { vector<int> weights = { 2, 3, 4, 5 }; vector<int> values = { 3, 4, 5, 6 }; int capacity = 8; cout << best_value(weights, values, capacity) << endl; // 输出13 return 0; } ``` 希望能够对你有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值