A container can own several objects through smart pointers.

owning container A `std::vector<std::unique_ptr<T>>` owns each object stored in the vector.

Vector Ownership

example
vector_ownership.cpp
Replay: real traced execution (multi-file project)
#include <iostream>
#include <memory>
#include <vector>

class Box {
private:
    int value;

public:
    Box(int start) {
        value = start;
    }

    int getValue() {
        return value;
    }
};

int main() {
    int first = 4;
    int second = 7;

    std::vector<std::unique_ptr<Box>> boxes;
    boxes.push_back(std::make_unique<Box>(first));
    boxes.push_back(std::make_unique<Box>(second));

    int total = 0;
    for (const std::unique_ptr<Box>& box : boxes) {
        total += box->getValue();
    }

    std::cout << "count=" << boxes.size() << std::endl;
    std::cout << "total=" << total << std::endl;
    return 0;
}
#include <iostream>
#include <memory>
#include <vector>

class Box {
private:
    int value;

public:
    Box(int start) {
        value = start;
    }

    int getValue() {
        return value;
    }
};

int main() {
    int first = 1;
    int second = 7;

    std::vector<std::unique_ptr<Box>> boxes;
    boxes.push_back(std::make_unique<Box>(first));
    boxes.push_back(std::make_unique<Box>(second));

    int total = 0;
    for (const std::unique_ptr<Box>& box : boxes) {
        total += box->getValue();
    }

    std::cout << "count=" << boxes.size() << std::endl;
    std::cout << "total=" << total << std::endl;
    return 0;
}
#include <iostream>
#include <memory>
#include <vector>

class Box {
private:
    int value;

public:
    Box(int start) {
        value = start;
    }

    int getValue() {
        return value;
    }
};

int main() {
    int first = 8;
    int second = 7;

    std::vector<std::unique_ptr<Box>> boxes;
    boxes.push_back(std::make_unique<Box>(first));
    boxes.push_back(std::make_unique<Box>(second));

    int total = 0;
    for (const std::unique_ptr<Box>& box : boxes) {
        total += box->getValue();
    }

    std::cout << "count=" << boxes.size() << std::endl;
    std::cout << "total=" << total << std::endl;
    return 0;
}
#include <iostream>
#include <memory>
#include <vector>

class Box {
private:
    int value;

public:
    Box(int start) {
        value = start;
    }

    int getValue() {
        return value;
    }
};

int main() {
    int first = 4;
    int second = 2;

    std::vector<std::unique_ptr<Box>> boxes;
    boxes.push_back(std::make_unique<Box>(first));
    boxes.push_back(std::make_unique<Box>(second));

    int total = 0;
    for (const std::unique_ptr<Box>& box : boxes) {
        total += box->getValue();
    }

    std::cout << "count=" << boxes.size() << std::endl;
    std::cout << "total=" << total << std::endl;
    return 0;
}
#include <iostream>
#include <memory>
#include <vector>

class Box {
private:
    int value;

public:
    Box(int start) {
        value = start;
    }

    int getValue() {
        return value;
    }
};

int main() {
    int first = 4;
    int second = 10;

    std::vector<std::unique_ptr<Box>> boxes;
    boxes.push_back(std::make_unique<Box>(first));
    boxes.push_back(std::make_unique<Box>(second));

    int total = 0;
    for (const std::unique_ptr<Box>& box : boxes) {
        total += box->getValue();
    }

    std::cout << "count=" << boxes.size() << std::endl;
    std::cout << "total=" << total << std::endl;
    return 0;
}
  1. first ← 4, second ← 7, boxes ← (empty)

    19int main() {20    int first→ 4 = 4; //@first=1, 821    int second→ 7 = 7; //@second=2, 102223    std::vector<std::unique_ptr<Box>> boxes→ (empty);24    boxes(empty).push_back(std::make_unique<Box>(first4));25    boxes.push_back(std::make_unique<Box>(second));
  2. value ← 4

    pass 1 of 2
    9public:10    Box(int start4) {11        value→ 4 = start4;12    }
  3. boxes.push_back(std::make_unique<Box>(first));

    23std::vector<std::unique_ptr<Box>> boxes;24boxes(empty).push_back(std::make_unique<Box>(first4));25boxes(empty).push_back(std::make_unique<Box>(second7));
  4. value ← 7

    pass 2 of 2
    9public:10    Box(int start7) {11        value→ 7 = start7;12    }
  5. total ← 0

    24boxes.push_back(std::make_unique<Box>(first));25boxes(empty).push_back(std::make_unique<Box>(second7));2627int total→ 0 = 0;28for (const std::unique_ptr<Box>& box : boxes) {
  6. for (const std::unique_ptr<Box>& box : boxes)

    pass 1 of 2
    27int total = 0;28for (const std::unique_ptr<Box>& box(empty) : boxes(empty)) {29    total0 += box(empty)->getValue();30}
  7. int getValue()

    pass 1 of 2
    14int getValue() {15    return value4;16}
  8. total ← 4

    28for (const std::unique_ptr<Box>& box : boxes) {29    total→ 4 += box(empty)->getValue();30}
  9. for (const std::unique_ptr<Box>& box : boxes)

    pass 2 of 2
    27int total = 0;28for (const std::unique_ptr<Box>& box(empty) : boxes(empty)) {29    total4 += box(empty)->getValue();30}
  10. int getValue()

    pass 2 of 2
    14int getValue() {15    return value7;16}
  11. total ← 11

    28for (const std::unique_ptr<Box>& box : boxes) {29    total→ 11 += box(empty)->getValue();30}
  12. std::cout << "count=" << boxes.size() << std::endl;

    32    std::cout << "count=" << boxes(empty).size() << std::endl;33    std::cout << "total=" << total11 << std::endl;34    return 0;35}
    outputcount=2
    total=11
  1. first ← 1, second ← 7, boxes ← (empty)

    19int main() {20    int first→ 1 = 1;21    int second→ 7 = 7;2223    std::vector<std::unique_ptr<Box>> boxes→ (empty);24    boxes(empty).push_back(std::make_unique<Box>(first1));25    boxes.push_back(std::make_unique<Box>(second));
  2. value ← 1

    pass 1 of 2
    9public:10    Box(int start1) {11        value→ 1 = start1;12    }
  3. boxes.push_back(std::make_unique<Box>(first));

    23std::vector<std::unique_ptr<Box>> boxes;24boxes(empty).push_back(std::make_unique<Box>(first1));25boxes(empty).push_back(std::make_unique<Box>(second7));
  4. value ← 7

    pass 2 of 2
    9public:10    Box(int start7) {11        value→ 7 = start7;12    }
  5. total ← 0

    24boxes.push_back(std::make_unique<Box>(first));25boxes(empty).push_back(std::make_unique<Box>(second7));2627int total→ 0 = 0;28for (const std::unique_ptr<Box>& box : boxes) {
  6. for (const std::unique_ptr<Box>& box : boxes)

    pass 1 of 2
    27int total = 0;28for (const std::unique_ptr<Box>& box(empty) : boxes(empty)) {29    total0 += box(empty)->getValue();30}
  7. int getValue()

    pass 1 of 2
    14int getValue() {15    return value1;16}
  8. total ← 1

    28for (const std::unique_ptr<Box>& box : boxes) {29    total→ 1 += box(empty)->getValue();30}
  9. for (const std::unique_ptr<Box>& box : boxes)

    pass 2 of 2
    27int total = 0;28for (const std::unique_ptr<Box>& box(empty) : boxes(empty)) {29    total1 += box(empty)->getValue();30}
  10. int getValue()

    pass 2 of 2
    14int getValue() {15    return value7;16}
  11. total ← 8

    28for (const std::unique_ptr<Box>& box : boxes) {29    total→ 8 += box(empty)->getValue();30}
  12. std::cout << "count=" << boxes.size() << std::endl;

    32    std::cout << "count=" << boxes(empty).size() << std::endl;33    std::cout << "total=" << total8 << std::endl;34    return 0;35}
    outputcount=2
    total=8
  1. first ← 8, second ← 7, boxes ← (empty)

    19int main() {20    int first→ 8 = 8;21    int second→ 7 = 7;2223    std::vector<std::unique_ptr<Box>> boxes→ (empty);24    boxes(empty).push_back(std::make_unique<Box>(first8));25    boxes.push_back(std::make_unique<Box>(second));
  2. value ← 8

    pass 1 of 2
    9public:10    Box(int start8) {11        value→ 8 = start8;12    }
  3. boxes.push_back(std::make_unique<Box>(first));

    23std::vector<std::unique_ptr<Box>> boxes;24boxes(empty).push_back(std::make_unique<Box>(first8));25boxes(empty).push_back(std::make_unique<Box>(second7));
  4. value ← 7

    pass 2 of 2
    9public:10    Box(int start7) {11        value→ 7 = start7;12    }
  5. total ← 0

    24boxes.push_back(std::make_unique<Box>(first));25boxes(empty).push_back(std::make_unique<Box>(second7));2627int total→ 0 = 0;28for (const std::unique_ptr<Box>& box : boxes) {
  6. for (const std::unique_ptr<Box>& box : boxes)

    pass 1 of 2
    27int total = 0;28for (const std::unique_ptr<Box>& box(empty) : boxes(empty)) {29    total0 += box(empty)->getValue();30}
  7. int getValue()

    pass 1 of 2
    14int getValue() {15    return value8;16}
  8. total ← 8

    28for (const std::unique_ptr<Box>& box : boxes) {29    total→ 8 += box(empty)->getValue();30}
  9. for (const std::unique_ptr<Box>& box : boxes)

    pass 2 of 2
    27int total = 0;28for (const std::unique_ptr<Box>& box(empty) : boxes(empty)) {29    total8 += box(empty)->getValue();30}
  10. int getValue()

    pass 2 of 2
    14int getValue() {15    return value7;16}
  11. total ← 15

    28for (const std::unique_ptr<Box>& box : boxes) {29    total→ 15 += box(empty)->getValue();30}
  12. std::cout << "count=" << boxes.size() << std::endl;

    32    std::cout << "count=" << boxes(empty).size() << std::endl;33    std::cout << "total=" << total15 << std::endl;34    return 0;35}
    outputcount=2
    total=15
  1. first ← 4, second ← 2, boxes ← (empty)

    19int main() {20    int first→ 4 = 4;21    int second→ 2 = 2;2223    std::vector<std::unique_ptr<Box>> boxes→ (empty);24    boxes(empty).push_back(std::make_unique<Box>(first4));25    boxes.push_back(std::make_unique<Box>(second));
  2. value ← 4

    pass 1 of 2
    9public:10    Box(int start4) {11        value→ 4 = start4;12    }
  3. boxes.push_back(std::make_unique<Box>(first));

    23std::vector<std::unique_ptr<Box>> boxes;24boxes(empty).push_back(std::make_unique<Box>(first4));25boxes(empty).push_back(std::make_unique<Box>(second2));
  4. value ← 2

    pass 2 of 2
    9public:10    Box(int start2) {11        value→ 2 = start2;12    }
  5. total ← 0

    24boxes.push_back(std::make_unique<Box>(first));25boxes(empty).push_back(std::make_unique<Box>(second2));2627int total→ 0 = 0;28for (const std::unique_ptr<Box>& box : boxes) {
  6. for (const std::unique_ptr<Box>& box : boxes)

    pass 1 of 2
    27int total = 0;28for (const std::unique_ptr<Box>& box(empty) : boxes(empty)) {29    total0 += box(empty)->getValue();30}
  7. int getValue()

    pass 1 of 2
    14int getValue() {15    return value4;16}
  8. total ← 4

    28for (const std::unique_ptr<Box>& box : boxes) {29    total→ 4 += box(empty)->getValue();30}
  9. for (const std::unique_ptr<Box>& box : boxes)

    pass 2 of 2
    27int total = 0;28for (const std::unique_ptr<Box>& box(empty) : boxes(empty)) {29    total4 += box(empty)->getValue();30}
  10. int getValue()

    pass 2 of 2
    14int getValue() {15    return value2;16}
  11. total ← 6

    28for (const std::unique_ptr<Box>& box : boxes) {29    total→ 6 += box(empty)->getValue();30}
  12. std::cout << "count=" << boxes.size() << std::endl;

    32    std::cout << "count=" << boxes(empty).size() << std::endl;33    std::cout << "total=" << total6 << std::endl;34    return 0;35}
    outputcount=2
    total=6
  1. first ← 4, second ← 10, boxes ← (empty)

    19int main() {20    int first→ 4 = 4;21    int second→ 10 = 10;2223    std::vector<std::unique_ptr<Box>> boxes→ (empty);24    boxes(empty).push_back(std::make_unique<Box>(first4));25    boxes.push_back(std::make_unique<Box>(second));
  2. value ← 4

    pass 1 of 2
    9public:10    Box(int start4) {11        value→ 4 = start4;12    }
  3. boxes.push_back(std::make_unique<Box>(first));

    23std::vector<std::unique_ptr<Box>> boxes;24boxes(empty).push_back(std::make_unique<Box>(first4));25boxes(empty).push_back(std::make_unique<Box>(second10));
  4. value ← 10

    pass 2 of 2
    9public:10    Box(int start10) {11        value→ 10 = start10;12    }
  5. total ← 0

    24boxes.push_back(std::make_unique<Box>(first));25boxes(empty).push_back(std::make_unique<Box>(second10));2627int total→ 0 = 0;28for (const std::unique_ptr<Box>& box : boxes) {
  6. for (const std::unique_ptr<Box>& box : boxes)

    pass 1 of 2
    27int total = 0;28for (const std::unique_ptr<Box>& box(empty) : boxes(empty)) {29    total0 += box(empty)->getValue();30}
  7. int getValue()

    pass 1 of 2
    14int getValue() {15    return value4;16}
  8. total ← 4

    28for (const std::unique_ptr<Box>& box : boxes) {29    total→ 4 += box(empty)->getValue();30}
  9. for (const std::unique_ptr<Box>& box : boxes)

    pass 2 of 2
    27int total = 0;28for (const std::unique_ptr<Box>& box(empty) : boxes(empty)) {29    total4 += box(empty)->getValue();30}
  10. int getValue()

    pass 2 of 2
    14int getValue() {15    return value10;16}
  11. total ← 14

    28for (const std::unique_ptr<Box>& box : boxes) {29    total→ 14 += box(empty)->getValue();30}
  12. std::cout << "count=" << boxes.size() << std::endl;

    32    std::cout << "count=" << boxes(empty).size() << std::endl;33    std::cout << "total=" << total14 << std::endl;34    return 0;35}
    outputcount=2
    total=14

Sum Owned Boxes

  1. Start with an empty vector of unique_ptr<Box>.
  2. Push one box with value 4.
  3. Push one box with value 7.
  4. Loop over the owned boxes by reference.
  5. Add each box value into total. | Box | Stored value | Running total | | --- | --- | --- | | first | 4 | 4 | | second | 7 | 11 |

Exercise: vector_ownership.cpp

Store two unique_ptr boxes in a vector, loop over them, and print the count and total