C ++中的模板类和函数重载

施纳格尔

我正在练习在C ++中使用模板和类。我的目标是为双端队列编写一个模板类。它具有“ insert_head”,“ insert_tail”,“ remove_tail”和“ remove head”的功能,以及使用“ cout”进行打印的功能。同样,必须使用'='运算符将类的一个实例复制到另一实例。这是我当前的代码:

#ifndef DEQUE_H
#define DEQUE_H

template <typename T>
class Deque {
public:
    Deque(int size = 0, int capacity = 1000) : size_(size), capacity_(capacity) 
    {}
    Deque(Deque & d) : x_(d.x()), size_(d.size()), capacity_(d.capacity()) {}


std::ostream & operator<<(std::ostream & cout) {
    cout << '[';

    if (size_ > 0) {
        for (int i = 0; i < (size_ - 1)* sizeof(T); i += sizeof(T)) {
            std::cout << *(x_ + i) << ',';
        }
        cout << *(x_ + (size_ - 1)* sizeof(T));
    }
    cout << ']';
    return cout;
}

Deque operator=(Deque d) {
    Deque dq(d);
    return dq;
}

void print_test() {
    std::cout << '[';

    if (size_ > 0) {
        for (int i = 0; i < (size_ - 1)* sizeof(T); i += sizeof(T)) {
            std::cout << *(x_ + i) << ',';
        }
        std::cout << *(x_ + (size_ - 1)* sizeof(T));
    }
    std::cout << ']';
}

int * x() {
    return x_;
}
int size() {
    return size_;
}
int capacity() {
    return capacity_;
}

bool is_empty() {
    return size_ == 0;
}

void insert_tail(T tail) {
    if (size_ < capacity_) {
        *(x_ + sizeof(T) * size_) = tail;
        size_++;
    } else {
        // throw overflow
    }
}
T remove_tail() {
    if (size_ > 0) {
        T ret = *(x_ + sizeof(T) * (size_ - 1));
        std::cout << ret;
        size_--;
        return ret;
    } else {
        // throw underflow
    }
}

void insert_head(T head) {
    if (size_ > 0 && size_ < capacity_) {
        for (int i = (size_ - 1) * sizeof(T); i < 0; i -= sizeof(T)) {
            *(x_ + i + sizeof(T)) = *(x_ + i);
        }
    }
    if (size_ < capacity_) {
        *x_ = head;
        size_++;
    } else {
        // throw overflow
    }
}

T remove_head() {

    if (size_ > 0) {
        T ret = *x_;
        for (int i = sizeof(T); i < size_* sizeof(T); i += sizeof(T)) {
            *(x_ + i - sizeof(T)) = *(x_ + i);
        }   
        size_--;
        return ret;
    } else {
        // throw underflow
    }
}

private:
    T * x_;
    int size_;
    int capacity_;
};

#endif

这是我使用该类的测试代码:

#include <iostream>
#include "Deque.h"

int main(int argc, char const *argv[])
{
    Deque< int > dq;


    dq.insert_head(1);

    // dq.insert_head(2); // adding head when not empty causes bug

    dq.insert_tail(3);
    dq.insert_tail(4);
    dq.insert_tail(5);
    dq.print_test(); std::cout << std::endl;

    // std::cout << dq; // '<<' not overloaded properly'

    std::cout << dq.remove_head() << " head removed\n";

    // int x = dq.remove_head(); // seg faults when assigning returned value to a variable 

    dq.insert_tail(2);
    dq.print_test();
    std::cout << std::endl;

    Deque< int > dq1(dq);
    Deque< int > dq2;

    // dq2 = dq1; // '=' not overloaded properly

    return 0;
}

我的四个问题中的每一个都在我的测试文件中的注释掉的代码行中,这里是进一步的解释:

  1. 当调用“ dq.insert_head(2)”并且dq不为空(大小> 0)时,我尝试将双端队列中的所有其他元素移到一个位置上,以便可以在此处插入新值,这是有问题的,并且元素不会移动。

  2. “ std :: cout << dq”不会像应有的那样打印dq。该代码与“ print_test()”方法非常相似,但是当我运行该程序时,出现错误“操作符<<不匹配”。这是因为它是模板类吗?还是我做其他完全错误的事情?

  3. 当尝试从双端队列中删除头部或尾部时,我试图返回已删除的值。在未注释掉的代码行中,将按原样打印返回的值,但是下面的代码行会导致段错误。是因为我正在尝试将模板varabale分配给整数变量吗?

  4. 我的最后一个问题是'='运算符未将类的一个实例复制到另一个。我的目标是创建该类的新实例,然后返回该实例(如您在“ Deque运算符=(Deque d)”中看到的那样),但这种方法没有按我希望的那样工作。使用模板类重载'='函数的最佳方法是什么。

感谢您的帮助,我们非常感谢您对这些问题的回答。

杰克·弗里曼

第一个问题的答案是删除,sizeof(T)因此您最终遇到了这个问题

    for (int i = (size_ - 1); i > 0; i --) {
        *(x_ + i + 1) = *(x_ + i);
    }

第二个问题的答案是将您的<<重载声明更改friend std::ostream & operator<<(std::ostream & x, Deque n)并在类之外初始化主体。

第三个问题的答案是,您不能返回一个int指针,该指针可能指向与T可能不同的内存位置块。

第四个问题的答案是执行以下操作:

Deque& operator=(const Deque& d) {
    x_ = d.x_; // Deep copy
    size_ = d.size_;
    capacity_ = d.capacity_;
    return *this;
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章