容器类与类的区别 - C++

3

我是一名新手程序员,最近遇到了这个任务:

创建一个容器类family,其中包含一个20个person对象的数组。

我在网上和书中查找了很多资料,但仍然无法理解C++中容器类和类之间的区别。

请问如何同时创建一个family类和20个person对象?


4
一个容器类就是它听起来的意思。它是一个作为其他对象的容器的类。 - NathanOliver
1
“向这个社区提问是我最后的选择。”那么,询问设置任务的人怎么样?是谁写了你不理解的话? - Lightness Races in Orbit
这可能也会对你有所帮助 http://en.cppreference.com/w/cpp/container - Ceros
它可能只是,πάνταῥεῖ。奥比万·克诺比已经死了。但是如果有机会真的想要搞砸教练的头脑,可以从这里开始:https://dev59.com/yWsz5IYBdhLWcg3wpZdF#7759622 - user4581301
@LightnessRacesinOrbit 这个问题是书中的一个项目。 - Minh Le
显示剩余3条评论
3个回答

10
"容器类"并不是官方术语,它只是在英文单词"class"旁加上一个描述性词语。这个任务要求您创建一个包含其他内容的类;即一个由20个"person"对象数组组成的类。
最基本的实现可以如下所示:
class family
{
public:
   person people[20];
};

在现实生活中,你可能会这样做:
#include <array>
using family = std::array<person, 20>;

似乎每个家庭(甚至大多数家庭)都恰好有20个人的可能性不太大,所以我个人会选择:

#include <vector>
std::vector<person> family;

...并根据需要操纵向量。


3

C++是一种面向对象的语言,鼓励您进行“封装”。这需要将概念分组为对象,并以其数据值和可对该数据执行的操作进行描述。

因此,可以定义一个Account类,其中包含id和余额以及用于存款或提款货币的函数。这个定义形成了“类型”,但当您“实例化”(创建一个实例)这个类型时,即

Account a;

那么变量a在这个作用域中是指向一个类型为Account对象

有时你需要一个可以存储和追踪其他类型对象的类。这就是所谓的“容器类”,通常它结合了一个存储器和计数器。

假设我们想要存储一些float,我们可以直接写:

float store[64];

std::cout << "Enter the first number: ";
std::cin >> store[0];

但是我们如何追踪我们有多少浮动呢? 我们可能需要一个计数器。

float store[64];
int stored = 0;

std::cout << "Enter the first number: ";
std::cin >> store[0];
stored++;

std::cout << "Enter the second number: ";
std::cin >> store[1];
stored++;

这个方法可行,而且并不太难,但如果您正在编写一个期望接收存储器和其大小的函数,您该如何表达呢?

void myFunction(std::string label, float* store, int count);

这需要两个参数,不是特别明确。

C++关注封装:将“存储”和内容数量封装成一个类:

struct Store {
    float store_[64] {};
    int count_ {0};
};

这是一个容器。我们现在可以编写一个函数,使用单个参数接收包含其他值的对象:

void myFunction(std::string label, Store& store);  // & here = by reference

如果这是'C',你将编写直接操作存储中值的代码:
store.store_[N] = 1;
store.count_++;

但这样做比较麻烦,我们没有检查是否有空间。在C++中,我们可以将其封装到类描述中的成员函数中,并隐藏成员变量,以便您必须通过我们指定的接口来操作数据。

#include <iostream>

class Store {
    enum { MaxCount = 64 };
    float store_[MaxCount] {};
    size_t count_ = 0;
public:
    // return the maximum number of elements we can store
    size_t capacity() const { return MaxCount; }
    // true/false: is the store empty?
    bool empty() const { return count_ == 0; }
    // return the current count
    size_t size() const { return count_; }

    bool add(float value) {
        if (count_ >= capacity()) {
            std::cerr << "store is full!\n";
            return false;
        }
        store_[count_] = value;
        ++count_;
    }
    // reset
    void clear() {
        count_ = 0;  // we don't actually need to change the store
    }
    // allow array-like usage
    const float& operator[](size_t index) const { return store_[index]; }
    float& operator[](size_t index) { return store_[index]; }
    // provide bounds-checked array-ish access
    float at(size_t index) const {
        if (index >= count_)
            throw std::invalid_argument("array index out of bounds");
        return store_[index];
    }
};

int main() {
    Store store;
    for (size_t i = 0; i < store.capacity(); ++i) {
        std::cout << "Enter number #" << i << " or -ve to stop: " << std::flush;
        float f = -1;
        std::cin >> f;
        std::cout << "\n" << f << "\n";
        if (f < 0)
            break;
        store.add(f);
    }
    std::cout << "You entered " << store.size() << " values:";
    for (size_t i = 0; i < store.size(); ++i) {
        std::cout << ' ' << store[i];
    }
    std::cout << '\n';
}

现场演示:http://ideone.com/boE3Ki


0
他们告诉你创建一个作为数组容器的类。在编程中,特别是当你刚开始学习时,你会看到许多被称为容器的元素,因为你的老师希望你将变量、类和数组(以及其他编程工具)视为可以存储数据的容器。
这种方式来看待编程使得你更容易将信息概念化,尤其是当你涉及到指针等更复杂的概念时。
所以,长话短说,创建一个包含数组的类。如果你正在学习构造函数和重载,请确保根据传入的数据进行初始化。如果没有,完成该项目只需要几行代码即可。

1
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - NathanOliver

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接