2016-12-07 55 views
0

我想寫自己的簡單的轉發列表實現。我想通過cout < < list [0]訪問元素。我寫了下面的代碼,而不是價值,我得到了像x637c00539997。我做錯了什麼? 我的代碼還可以改進嗎?內存地址,而不是在類的cout值

#include <iostream> 
#include <assert.h> 
#include <cstdio> 
#include <cstring> 
#include <memory> 

using namespace std; 

class myList{ 
public: 

    class myListExceptionEmpty: public exception 
    { 
    public: 
    virtual const char* what() const throw() 
    { 
     return "EMPTY"; 
    } 
    }; 

    void push_back(int valve); 
    int getSize(); 
    bool isEmpty(); 
    void removeFirst(); 
    void remove(int x); 
    void dump(); 
    void pop_front(); 
    struct elem 
    { 
    std::shared_ptr<elem> next; 
    int val; 
    }; 
    class proxy 
    { 
    public: 
    std::shared_ptr<myList::elem> position; 
    proxy(std::shared_ptr<myList::elem> pos) 
    { 
     position = pos; 
    } 
    }; 
    std::shared_ptr<myList::proxy> operator[](int position); 

private: 
    std::shared_ptr<elem> start; 
    std::shared_ptr<elem> getLastElement(); 
    std::shared_ptr<proxy> current; 
    int size = 0; 


}; 

ostream& operator<<(std::ostream& os, myList::proxy& obj) 
{ 
     os << obj.position->val; 
     return os; 
} 

shared_ptr<myList::proxy> myList::operator[](int position) 
{ 
    std::shared_ptr<elem> p = start; 
    for(int i=0;i<position;i++) 
    { 
    p = p->next; 
    if (p == NULL) throw std::out_of_range("out"); 
    } 
    //cout << p->val; 
    std::shared_ptr<proxy> tmp(new myList::proxy(p)); 
    current = tmp; 
    return current; 
} 

std::shared_ptr<myList::elem> myList::getLastElement() 
{ 
    std::shared_ptr<elem> p = start; 
    while(p->next != NULL) p = p->next; 
    return p; 
} 

bool myList::isEmpty() 
{ 
    return size; 
} 

void myList::dump() 
{ 
    std::shared_ptr<elem> x = start; 
    while (x != NULL) 
    { 
     cout << x->val << endl; 
     x = x->next; 
    } 
} 

void myList::push_back(int valve) 
{ 
    std::shared_ptr<elem> p, n(new elem()); 
    n->next = NULL; 
    n->val = valve; 
    p = start; 
    if(p != NULL) 
    { 
    while(p->next != NULL) p = p->next; 
    p->next = n; 
    } 
    else start = n; 
    size++; 

} 

void myList::remove(int x) 
{ 
    if (size == 0) throw myListExceptionEmpty(); 
    std::shared_ptr<elem> p, prv; 
    p = start; 
    while(p->next != NULL) 
    { 
    if (p->val == x) 
    { 
     prv->next = p->next; 
     size--; 
    } 
    prv = p; 
    p = p->next; 
    } 
} 

void myList::pop_front() 
{ 

    if (size == 0) throw myListExceptionEmpty(); 
    std::shared_ptr<elem> p, prv; 
    p = start; 
    while(p->next != NULL) 
    { 
    prv = p; 
    p = p->next; 
    } 
    prv->next = NULL; 

} 
void myList::removeFirst() 
{ 
    if (size == 0) throw myListExceptionEmpty(); 
    std::shared_ptr<elem> p; 
    p = start; 
    cout << start->val << endl; 
    if(p!= NULL) 
    { 
    start = p->next; 
    } 
    size--; 

} 

int myList::getSize() 
{ 
    return size; 
} 

int main() 
{ 
    myList array; 
    int size; 
    cin >> size; 

    char a; 
    int tmp; 
    for (int i=0; i<size; ++i) { 
    std::cin >> a; 
    if (a == 'D') 
    { 
     try{ 
     array.removeFirst(); 
    } 
    catch (myList::myListExceptionEmpty &e) 
    { 
     cout << e.what() << endl; 
    } 
    } 
    else if (a == 'A') 
    { 
     int tmp; 
     std::cin >> tmp; 
     array.push_back(tmp); 
     cout << "elem" << array[0]; 
    } 
    else if (a == 'S') cout /*<< "Size:"*/ << array.getSize() << endl; 
    } 

} 
+0

你'操作符[]'返回'的shared_ptr ',那麼你是怎麼想到要得到印? –

+0

os << *(obj.position-> val);給我錯誤:錯誤:一元'*'的無效類型參數(有'int') – piotr712

回答

1

關於這個問題: 「還有什麼要改進」:

  • 您使用的共享指針,太棒了!而不是使用new使用相應的例程make_shared(請參閱C++文檔)。
  • 不要在類中定義類。讓每個類都有自己的頭文件和源文件。它極大地提高了可讀性,甚至通過將所有類拆分成不同的文件來更快地編譯(最好的方法:使用包含防護)。這樣您也可以保留名稱空間,如myList::elem。使用<cassert>代替<assert.h>。無論如何,你使用C++ 11,那麼爲什麼需要使用舊的C庫?!
  • 只是一個例子:將void myList::remove(int x)更改爲void myList::remove(const int& x)。讓編譯器知道x是隻讀對象。不要在這裏調用int-copy構造函數(也在其他代碼行中)。

關於你的第二個問題:你的重載操作符[]返回一個共享指針而不是這個指針指向的對象。因此,它將打印指針的地址。

+0

謝謝,你可以給任何提示如何讓cout << list [0]工作? – piotr712

+1

@ piotr712你嘗試解除引用:'cout << * list [0]'? –

+1

怎麼樣'cout << * list [0] << endl'?這是否工作? – Kapa11

0

這是修復後的程序。我用cout < < * array [0];而不是cout < < array [0] ;.比你的幫助

#include <iostream> 
#include <memory> 

using namespace std; 
class MyListProxy; 
class MyListExceptionEmpty: public exception 
{ 
public: 
    virtual const char* what() const throw(){ 
    return "EMPTY"; 
    } 
}; 



class MyList{ 
public: 
    void push_back(int valve); 
    int getSize() { return size; }; 
    bool empty() { return size; }; 
    void removeFirst(); 
    void remove(const int& x); 
    void dump(); 
    void pop_front(); 
    void clear() {this->start = NULL; size = 0;} 
    struct elem 
    { 
    shared_ptr<elem> next; 
    int val; 
    }; 
    shared_ptr<MyListProxy> operator[](int position); 
private: 
    shared_ptr<elem> start; 
    shared_ptr<MyListProxy> current; 
    shared_ptr<elem> getEnd(); 
    int size = 0; 

}; 

class MyListProxy 
{ 
public: 
    shared_ptr<MyList::elem> position; 
    MyListProxy(shared_ptr<MyList::elem> pos) 
    { 
    position = pos; 
    } 
}; 

ostream& operator<<(ostream& os, MyListProxy& obj) 
{ 
    os << obj.position->val; 
    return os; 
} 

shared_ptr<MyListProxy> MyList::operator[](int position) 
{ 
    if (start == NULL) throw out_of_range("out"); 
    shared_ptr<elem> p = start; 
    for(int i=0;i<position;i++){ 
    p = p->next; 
    if (p == NULL) throw out_of_range("out"); 
    } 
    return make_shared <MyListProxy>(p); 
} 

shared_ptr<MyList::elem> MyList::getEnd() 
{ 
    if (start == NULL) return start; 
    shared_ptr<elem> p = start; 
    while(p->next != NULL) p = p->next; 
    return p->next; 
} 

void MyList::dump() 
{ 
    shared_ptr<elem> x = start; 
    while (x != NULL) 
    { 
    cout << x->val << endl; 
    x = x->next; 
    } 
} 

void MyList::push_back(int valve) 
{ 
    shared_ptr<elem> p; 
    auto last = this->getEnd(); 
    auto a = make_shared<elem>(); 
    last = a; 
    last->val = valve; 
    size++; 

} 

void MyList::remove(const int& x) 
{ 
    if (size == 0) throw MyListExceptionEmpty(); 
    shared_ptr<elem> p, prv; 
    p = start; 
    while(p->next != NULL) 
    { 
    if (p->val == x) 
    { 
     prv->next = p->next; 
     size--; 
    } 
    prv = p; 
    p = p->next; 
    } 
} 

void MyList::pop_front() 
{ 

    if (size == 0) throw MyListExceptionEmpty(); 
    start = start->next; 
} 


int main() 
{ 
    MyList array; 
    int size; 
    cin >> size; 

    char a; 
    int tmp; 
    for (int i=0; i<size; ++i) { 
    cin >> a; 
    if (a == 'D') 
    { 
     try{ 
     cout << *array[0]; 
     array.pop_front(); 
     } 
     catch (MyListExceptionEmpty &e) 
     { 
     cout << "EMPTY" << endl; 
     } 
     catch (out_of_range &e) 
     { 
     cout << "EMPTY" << endl; 
     } 
    } 
    else if (a == 'A') 
    { 
     int tmp; 
     cin >> tmp; 
     array.push_back(tmp); 
    } 
    else if (a == 'S') cout /*<< "Size:"*/ << array.getSize() << endl; 
    cout << "SIZE::" << array.getSize() << endl; 
    } 

}