c++ - 实现一个数组类,作业麻烦

标签 c++ arrays

正如标题所说,我的任务之一是实现一个数组类。教授给了我们开始的标题样式,为我们创建了函数声明。使用前面的示例,我已尽力定义这些函数,但我在理解正在发生的事情时遇到了很多麻烦。发布整个头文件可能有点多,但我会尽力解释我遇到的问题。这是我的代码:

#ifndef ARRAY_H
#define ARRAY_H
#include <iostream>
#include <string>
using namespace std;

template <class T>
class Array {
private:
    int size;
    T * arr;
public:
    int getSize();

    Array();
    Array(int size);
    Array(Array & other);
    Array(T[], int n);
    ~Array();
    Array & operator=(Array & rhs);
    Array & operator+(Array & rhs); // append
    T & operator[](int i); //allow read and write
    const T & operator[](int n) const; // readonly
    void print(int n = 5);
    void print(ostream & out, int n);
    operator int *() { return arr; }
    friend ostream & operator <<(ostream & out, Array <T>& rhs);
};

template <class T>
int Array<T>::getSize() {
    return size;
}

template <class T>
Array<T>::Array() {
    arr = new T[];
}

template <class T>
Array<T>::Array(int size) {
    arr = new T[size];
}

template <class T>
Array<T>::Array(Array & other) {
    size = other.getSize();
    arr = new T[size];
    copy(arr[0], arr[size + 1], other.arr[0]);
}

template <class T>
Array<T>::Array(T[], int n) {
    size = n;
    arr = new T[n];
}

template <class T>
Array<T>::~Array() {
    if (arr) {
        delete arr;
    }
}

template <class T>
Array<T>& Array<T>::operator=(Array & rhs) {
    if (this != &rhs) {
        delete[] arr;
        size = rhs.getSize();
        arr = new T[size];
        copy(arr[0], arr[size+1], rhs.arr[0]);
    }
    return *this;
}

template <class T>
Array<T>& Array<T>::operator+(Array & rhs) {
    Array *tmp;

    tmp = new Array(size + rhs.getSize());
    return *tmp;
}

template <class T>
T& Array<T>::operator[](int i) {
    assert(0 <= i && i < size);
    return arr[i];
}

template <class T>
const T& Array<T>::operator[] (int n) const {
    assert(0 <= i && i < size);
    return arr[i];
}

template <class T>
void Array<T>::print(ostream &out, int n) {
    for (size_t i = 0; i < n; i++) {
        out << arr[i] << " ";
    }
}

template <class T>
void Array<T>::print(int n = 5) {
     print(cout, n);
}

template <class T>
ostream & operator << (ostream & out, Array<T> & rhs) {
    out << "( " << rhs.getSize() << ")";
    return out;
}

#endif

我会很感激任何和所有的提示,只是为了帮助我弄清楚这门课上发生了什么。如果最终要求太多,我很抱歉。

编辑:再次感谢大家的帮助!链接器错误已修复。我应该指定 print 是类的成员,而不仅仅是免费的。

最佳答案

  1. When trying to do a copy constructor for Array(Array & other); on line 46, I get the error error C2664: 'char *strcpy(char *,const char *)' : cannot convert argument 1 from 'int *' to 'char *' It keeps pointing to the strcpy function, but I'm not sure what it's asking me to change. I get two errors for the same line, the second of which says cannot convert argument 1 from 'std::string *' to 'char *'

这里的问题是 strcpy旨在复制char两个内存位置之间的类型。但是,您的模板参数 T可以是任何类型,所以使用 strcpy如果你想要通用性,这里是相当不合适的。复制构造函数的直接(但不是很有效)实现类似于:

template <class T>
Array<T>::Array(const Array &other) : size(other.size), arr(new T[size])
{
  for (int i = 0; i < size; ++i)
    arr[i] = other.arr[i];
}

2) I get another error with trying to strcpy function on line 71 when writing the operator= overloader. It tells me cannot convert argument 1 from 'std::string *' to 'char *'

同样,它与一个问题相同:较旧的 C 风格 str*函数与原始 char * 一起使用指向包含字符的一些内存块的指针。因此,这些函数组不能直接与 std::string 一起使用。来自标准 c++ 库,没有一些改编。大多数时候您不想这样做,因为这些函数可能会发生变异 std::string不保留其危险的内部不变量。

对于赋值运算符,你可以只做一个 copy-and-swap :

template <class T>
Array<T>& Array<T>::operator = (Array rhs)
{
  std::swap(size, rhs.size);
  std::swap(arr, rhs.arr);
  return *this;
}

3) For the T & operator[](int i); //allow read and write on line 85, I'm wondering if I'm supposed to create a new array with i slots. The allow, read, and write comment the professor left confused me. Also, for the following function, Array<T>::T & operator[] (int n) const; the comment said read only, so I assumed I was just supposed to return the array with n items.

operator []用于提供语法糖以访问您的 Array<T> 中的特定项目给出一些索引 i .没有它,以下内容将无法工作:

Array<int> arr(42);
std::cout << arr[0];

因此,您不必在此运算符内分配任何内容。您可以用相同的方式实现 const 和非常量版本。唯一的区别是一个人会有一个const最后的限定符,所以这将适用于 const Array<T>还有:

template <class T>
T& Array<T>::operator[] (int i) 
{
  assert(0 <= i && i < size);
  return arr[i];
}

template <class T>
const T& Array<T>::operator[] (int i) const
{
  assert(0 <= i && i < size);
  return arr[i];
}

4) I left a comment for the void print(int n = 5); function. But to summarize, I want to be able to print out a certain number of items in the array per line, but there's no multidimensional array. I attempted two for loops, but it just got stuck on the same array item.

5) I'm not sure why void print(ostream & out, int n); is needed. Is it supposed to override the above print statement?

您正在寻找的正确术语是“重载”。 “覆盖”在 C++ 命名法中具有非常具体的含义,不适用于这种情况。

从声明来看,第二个的意图似乎是print signature 是为了支持不同类型的输出流(其中 cout 是一种类型 btw)。您在这里要做的是实现 print 的第一个版本。就第二个而言。事实上,它们甚至根本不需要是模板函数:

void print(ostream &out, int n)
{
  for (size_t i = 0; i < n; ++i)
    out << pets[i] << " ";
}

void print(int n)
{
  print(cout, n);
}

请注意,print可能应该修改为将数组打印出来,而不是在此处引用一个(全局?)特定实例。

编辑:修改print时要将数组打印出来,它当然必须是一个模板。一种可能的签名:

  template <typename T>
  void print(const Array<T> &arr, int n)
  {
    print(arr, n, cout);
  }

关于c++ - 实现一个数组类,作业麻烦,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20043407/

相关文章:

c++ - 在信号处理程序中使用 `std::shared_ptr` 和 `std::weak_ptr` 是否安全?

javascript - 基于嵌套值或提升值的深度排序多维数组

javascript - 如何将字符串数组发送到数据库并一次搜索一个值

c++ - 为什么这个例子使用 ASIO async_receive_from 而不是 "leaky"

c++ - 双图插入问题

c++ - 在 C++ 的方法返回中组合多个值

c++ - 如何正确转换日期时间字符串的 utc 时间位移?

java - 如何将两个int数组混合成唯一的xy坐标Map?

c# - 如何在 C# 中比较数组?

javascript - arr.push(arr.splice(n,1)) "swallows"被移动对象的属性