我是一名新手程序员,最近遇到了这个任务:
创建一个容器类family,其中包含一个20个person对象的数组。
我在网上和书中查找了很多资料,但仍然无法理解C++中容器类和类之间的区别。
请问如何同时创建一个family类和20个person对象?
我是一名新手程序员,最近遇到了这个任务:
创建一个容器类family,其中包含一个20个person对象的数组。
我在网上和书中查找了很多资料,但仍然无法理解C++中容器类和类之间的区别。
请问如何同时创建一个family类和20个person对象?
class family
{
public:
person people[20];
};
#include <array>
using family = std::array<person, 20>;
似乎每个家庭(甚至大多数家庭)都恰好有20个人的可能性不太大,所以我个人会选择:
#include <vector>
std::vector<person> family;
...并根据需要操纵向量。
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
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';
}