简体   繁体   English

我如何在以后实例化数组的大小?

[英]How do I instantiate an array's size later?

Let's say I have a base class called 假设我有一个名为的基类

Class Base {
public:
    std::string array[];
};

The size the string array is not decided until another class extends it, what's the correct syntax for doing so? 字符串数组的大小在另一个类扩展之前没有决定,这样做的正确语法是什么?

EG, later on in a derived class EG,稍后在派生类中

Derived::Derived() {
    array[] = new array[40];
}

If you want to use a C-style array, the size must be fixed and known at compile-time . 如果要使用C样式数组,则必须在编译时修复并知道大小。 And even in that case, you could use the safer, zero-overhead std::array<> wrapper instead. 即使在这种情况下,您也可以使用更安全,零开销的std::array<>包装器。

If the size of your container is not known at compile-time, then it is good practice to use std::vector (or std::deque in some cases, based on your requirements in terms of memory allocation) and avoid manual memory management through raw pointers, new[] and delete[] : 如果在编译时知道容器的大小,那么最好使用std::vector (或者在某些情况下根据内存分配的要求使用std::deque )并避免手动内存管理通过原始指针, new[]delete[]

#include <string> // For std::string
#include <vector> // For std::vector

class Base {
public:
    std::vector<std::string> myVector;
};

Besides, this design won't require any dedicated work in the constructor (and destructor) of Derived . 此外,此设计不需要Derived的构造函数(和析构函数)中的任何专门工作。 If all that was done by Derived 's default constructor was to allocate the array, now you can avoid explicitly defining a default constructor at all, and let the compiler generate one for you implicitly - same story for the destructor. 如果Derived的默认构造函数完成的所有操作都是分配数组,那么现在可以避免显式定义默认构造函数,并让编译器为您隐式生成一个 - 析构函数的相同故事。

Also, I would discourage you from using names of standard container classes (like array ) as names for your variables. 另外,我不鼓励您使用标准容器类(如array )的名称作为变量的名称。 Something like myArray (or myVector , as in my example above) are more appropriate choices. myArray (或myVector ,如上例中的)更合适的选择。

You don't. 你没有。 Arrays in C++ are of compile-time fixed size. C ++中的数组是编译时固定大小的。 You cannot just resize them to your liking. 你不能只是根据自己的喜好调整它们。

The bad way to do this using only language features is to actually have your member as an std::string* : 仅使用语言功能执行此操作的不好方法是将您的成员实际作为std::string*

std::string* array;

And then dynamically allocate an array of std::string s, assigning the pointer to the first element to array : 然后动态分配一个std::string s数组,将指向第一个元素的指针分配给array

Derived::Derived() {
    array = new std::string[40];
}

The good way to do this is to use library features. 这样做的好方法是使用库功能。 The standard library provides container types for you to use. 标准库提供了您可以使用的容器类型。 Try a std::vector<std::string> : 尝试std::vector<std::string>

std::vector<std::string> array;

Which you could initialise to contain 40 strings like so: 您可以初始化包含40个字符串,如下所示:

Derived::Derived()
  : array(40)
{ }

Why not use a std::vector<std::string> so that you don't have to worry about size. 为什么不使用std::vector<std::string>这样就不必担心大小了。 The container resizes automagically as new things are inserted into it. 容器会在插入新内容时自动调整大小。

Using a vector of string is normally better solution. 使用字符串向量通常是更好的解决方案。

But this will work: 但这会奏效:

Class Base {
Public:
    std::string *array;
};
Derived::Derived() {
    array = new array[40];
}

I'd add: 我补充说:

Class Base {
Public:
    std::string *arr;
    Base():arr(nullptr){}
    Base(sizr_t s):arr(new std::string[s]){}
    ~Base(){delete []arr;}
};
Derived::Derived():Base(40) {  }

And you may need to write copy/move constructors and asignments. 您可能需要编写复制/移动构造函数和asignments。 Derived dont have to know about very much. 派生不必非常了解。 Now compare with: 现在比较:

Class Base {
Public:
    std::vector<std::string> arr;
    Base(){}
    Base(sizr_t s):arr(s){}
};

All other special functions: destructor, copy/move constructors and asignments are generated by compiler. 所有其他特殊功能:析构函数,复制/移动构造函数和asignments由编译器生成。 And the constructor of Derived is still: Derived::Derived():Base(40) { } Also... you may want to make arr private or at least protected? Derived的构造函数仍然是:Derived :: Derived():Base(40){}另外......你可能想让arr私有或至少受到保护?

正确的语法是

std::vector<std::string> array;

As well as the done-to-death heap allocation, you can size it statically as in: 除了完成到堆的分配,您可以静态地调整它的大小,如下所示:

template <int N>
class Base
{
  public:
    std::string array[N];
};

class Derived : Base<40>
{ ... }

Pros: simple, avoids (relatively slow) memory allocation at runtime and the hassles of cleanup (smart array pointer or otherwise). 优点:简单,避免(运行时相对较慢)内存分配和清理麻烦(智能数组指针或其他)。 Cons: each instantiation of Base is a distinct type, which can lead to a little more bloat and less interoperability. 缺点:Base的每个实例都是一种不同的类型,这可能会导致更多的膨胀和更少的互操作性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM