【问题标题】:Internal templated class c++内部模板类 c++
【发布时间】:2018-11-28 13:37:18
【问题描述】:

我正在尝试我的 c++ 课程中的这个小练习,并且从现在开始我已经设法做到了。

它还没有完全完成,但现在我面临着内部类模板的永恒问题。

我在堆栈和其他网站上看到了很多不同的解决方案,但仍然缺少一些东西。 + 我最后的目标也是理解“为什么”。

它是迭代到我的数组所需的迭代器内部类。我已经看到一些示例为 External 和 Iternal 类提供 2 个不同的类型名,然后使用 typedef,但我不确定实现它的最佳方法是什么。

正如你所理解的,我的 Iterator 类需要采用与我的 Array 类相同的类型。

我肯定需要更改一些函数签名并在这里和那里添加一些 ,但现在我只需要避免所有模板陷阱。

using namespace std;

template <typename T>
class Iterator;

template<typename T>
class Array{

    T* _data;
    size_t _size;
    Iterator* _start;

public:

    class Iterator{
        T* content;

    public:
        explicit Iterator(T* value):content(value){}

        Iterator& operator++(){
            ++content;
            return *this;
        }

        T* operator*(){
            return content;
        }

        bool operator ==(const Iterator& o)const{
            if(content == o.content){
                return true;
            }
            return false;
        }

        bool operator !=(const Iterator& o)const{
            return !(*this == o);
        }
    };


    Array(const size_t s):_size(s){
        _data = new T[_size]();
        _start = new Iterator(_data);
    }

    Array(const Array& o):_size(o._size), _data(o._data), _start(o._start){}

    Array(const std::initializer_list<T>& list):_size(list.size()){
        auto start = list.begin();
        auto fin = list.end();

        _data = new T[_size];

        size_t index = 0;
        while(start != fin){
        _data[index++] = *start++;
        }

        _start = new Iterator(_data);
    }

    virtual ~Array(){
        cout << "~Array" << endl;
        delete[] _data;
    }

    Array<T>& operator= (const Array& o){
        if(this != &o){
            delete[] _data;

            for (size_t i = 0; i < o._size; ++i) {
                _data[i] = o._data[i];
            }
            _size = o._size;
        }

        return *this;
    }

    T& operator[](const size_t index){
        if(index < _size){
            return *_data[index];
        }
    }

    const size_t size()const{
        return _size;
    }

    Iterator begin(){
        return Iterator(_data[0]);
    }

    Iterator end(){
        return Iterator(_data[_size-1]);
    }

};

你能给我一个线索或帮助我吗?

这里是我的基本主要内容:

#include "Array.h"

int main() {

    Array<string> array({"h","e","l","l","o"});

    for (Array<string>::Iterator i = array.begin(); i != array.end(); ++i)
        cout << *i << endl;

    return 0;
}

谢谢!

【问题讨论】:

  • 什么是“内部类模板的永恒问题”?这不编译吗?
  • 您有两种不同的 Iterator 类型,从而使编译器感到困惑。没有办法在类外转发声明嵌套类型,所以跳过它。您可以将private 部分移到类的末尾,以便嵌套的Iterator 可见。
  • 你的_start 和你的_data 有什么区别,我的理解是它们有不同的类型,但代表的是同一个东西
  • @Tyker 之类的,_data 是我的数组容器(即指向数组第一个 case 的指针),start 是一个 Iterator 指向 _data 的第一个 case,用来遍历它.
  • @BoPersson 谢谢,它认为这是我的重大错误。我编辑了它并使用函数 start() 删除了这个 _start 迭代器来返回它。稍微简单一点,因为 start() 总是需要计算它,但是对于这个练习来说它就可以了。谢谢

标签: c++ class templates nested internal


【解决方案1】:

在全局范围内没有模板Iterator,所以这是错误的:

template <typename T>
class Iterator;

另外,Array&lt;T&gt;::Iterator 不是模板,它只是一个内部类。您可以像这样在类中简单地前向声明它:

template<typename T>
class Array {
public:
    class Iterator;

那么您的代码中存在一些错误(例如,end() 应该在最后一个元素之后 1,您需要取消引用迭代器两次并从指针构造一个)。

这是一个固定版本:

#include <iostream>
#include <string>

using namespace std;

template<typename T>
class Array {

    T* _data;
    size_t _size;
public:
    class Iterator;
private:
    Iterator* _start;

public:

    class Iterator {
        T* content;

    public:
        explicit Iterator(T* value) :content(value) {}

        Iterator& operator++() {
            ++content;
            return *this;
        }

        T* operator*() {
            return content;
        }

        bool operator ==(const Iterator& o)const {
            if (content == o.content) {
                return true;
            }
            return false;
        }

        bool operator !=(const Iterator& o)const {
            return !(*this == o);
        }
    };


    Array(const size_t s) :_size(s) {
        _data = new T[_size]();
        _start = new Iterator(_data);
    }

    Array(const Array& o) :_size(o._size), _data(o._data), _start(o._start) {}

    Array(const std::initializer_list<T>& list) :_size(list.size()) {
        auto start = list.begin();
        auto fin = list.end();

        _data = new T[_size];

        size_t index = 0;
        while (start != fin) {
            _data[index++] = *start++;
        }

        _start = new Iterator(_data);
    }

    virtual ~Array() {
        cout << "~Array" << endl;
        delete[] _data;
    }

    Array<T>& operator= (const Array& o) {
        if (this != &o) {
            delete[] _data;

            for (size_t i = 0; i < o._size; ++i) {
                _data[i] = o._data[i];
            }
            _size = o._size;
        }

        return *this;
    }

    T& operator[](const size_t index) {
        if (index < _size) {
            return *_data[index];
        }
    }

    const size_t size()const {
        return _size;
    }

    Iterator begin() {
        return _start;
    }

    Iterator end() {
        return Iterator(_data + _size);
    }

};

int main() {
    Array<string> array({ "h","e","l","l","o" });

    for (Array<string>::Iterator i = array.begin(); i != array.end(); ++i)
        cout << **i << endl;
}

【讨论】:

  • PS:我不知道_start 是干什么用的,没用过。我把它放在那里以防万一。
  • 抱歉是错的,_start 是我将从 Array 类中的 begin() 方法返回的内容
【解决方案2】:

感谢@rustyx 的帮助, 离它不远,但真的谢谢你。

我将在此处发布我更正且有效的代码,以防它可以帮助其他人。

#include <cstdlib>
#include <string>
#include <iostream>

using namespace std;


template<typename T>
class Array{

T* _data;
size_t _size;

public:

    class Iterator{
        T* content;

    public:
        explicit Iterator(T* value):content(value){}

        Iterator& operator++(){
            ++content;
            return *this;
        }

        T& operator*(){
            return *content;
        }

        bool operator ==(const Iterator& o)const{
            if(content == o.content){
                return true;
            }
            return false;
        }

        bool operator !=(const Iterator& o)const{
            return !(*this == o);
        }
    };


Array(const size_t s):_size(s){
    _data = new T[_size]();
}

Array(const Array& o):_size(o._size){
    _data = new T[_size];
    for (size_t i = 0; i < o._size; ++i) {
        _data[i] = o._data[i];
    }
}

Array(const std::initializer_list<T>& list):_size(list.size()){
    auto start = list.begin();
    auto fin = list.end();

    _data = new T[_size];

    size_t index = 0;
    while(start != fin){
        _data[index++] = *start++;
    }

}

virtual ~Array(){
    cout << "~Array" << endl;
    delete[] _data;
}

Array<T>& operator= (const Array& o){
    if(this != &o){
        delete[] _data;

        for (size_t i = 0; i < o._size; ++i) {
            _data[i] = o._data[i];
        }
        _size = o._size;
    }

    return *this;
}

T& operator[](const size_t index){
    if(index < _size){
        return *_data[index];
    }
}

const size_t size()const{
    return _size;
}

Iterator begin(){
    return Iterator(_data);
}

Iterator end(){
    return Iterator(_data + _size);
}

};

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-08
    • 2015-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多