2014-10-20 3 views
0

Не удается получить перегрузку < < и не может распечатать экземпляр «Учетная запись», используя метод «getter» через узел. Не совсем уверен, какую дополнительную информацию вы можете предоставить, пожалуйста, просто попросите что-нибудь еще, что я не уточнил! С моей перегрузкой оператора, очевидно, что-то не так, но я не уверен, что это такое. Я, мм ... мог бы удвоить начало каждого кода.Перегрузка шаблонов и выходных операторов

Account.cpp

#include "Account.h" 
    namespace myNamespace{ 
    // CONSTRUCTOR 
    Account::Account(int initialValue) 
    { 
     acct_balance = initialValue; 
    } 
    //MUTATOR MEMBER FUNCTION 
    void Account::deposit(int amount) 
    { 
     acct_balance += amount; 
    } 


    void Account::withdraw(int amount) 
    { 
     acct_balance -= amount; 
    } 


    void Account::setName(std::string newName) 
    { 
     name = newName; 
    } 
    //QUERY MEMBER FUNCTION 
    int Account::balance() const 
    { 
     return acct_balance; 
    } 


    bool Account::has_funds() const 
    { 
     return (acct_balance > 0.0); 
    } 


    std::string Account::getName() 
    { 
     return name; 
    } 


    int& operator += (Account& a,const Account& b) 
    { 
     a.acct_balance += b.balance(); 
     return a.acct_balance; 
    } 


    std::ostream& operator << (std::ostream& out, const Account& a) 
    { 
     out << a.acct_balance; 
    } 
    }; 

main.cpp

#include <iostream> 
    #include <string> 
    #include "Account.h" 
    #include "Node.h" 




    using namespace myNamespace; 
    using namespace std; 


    int main() 
    { 
    Node<int>* intNode = new Node<int>(5); 
    Node<std::string>* stringNode = new Node<std::string>("hello"); 
    Account* acc1 = new Account(); 
    Node<Account>* accountNode = new Node<Account>(*acc1); 



    cout << "Initialised intNode with " << (intNode)->getData() << " ,\n"; 
    cout << "Initialised stringNode with " << stringNode->getData() << " ,\n"; 
    cout << "Intiialised accountNode with $" << accountNode << "." << endl; 
    return 0; 
    } 


    /* 
    Modify the Node class you produced in the last few weeks so that it becomes 
    a class template for a Node that can store a pointer to a generic type 
    instance. The constructor for your new Node returns a pointer to the newlycreated 
    Node instance, which has been created in the heap. Instantiate a 
    Node to store a pointer to an int; a pointer to a string; and a pointer to 
    an Account. 
    */ 

node.h

#ifndef NODE_H 
    #define NODE_H 
    #include <iostream> 
    using namespace std; 


    namespace myNamespace{ 
    { 
    template <class T> 
    class Node 
    { 
    public: 
     Node(T const& initData, Node<T>* const& initPrev = NULL, Node<T>* const& initNext = NULL); 
     void setData(T newData); 
     T getData(); 
     void setPrev(Node<T>* newPrev); 
     Node<T>* getPrev(); 
     void setNext(Node<T>* newNext); 
     Node<T>* getNext(); 


     friend std::ostream& operator << (std::ostream& out, const Node<T>& a); 
    private: 
     T data; 
     Node<T> *next; 
     Node<T> *prev; 
    }; 
    #include "Node.template" 
    } 
    #endif 

Node.template

template <class T> 
    Node<T>::Node(T const& initData, Node<T>* const& initPrev, Node<T>* const& initNext) 
    { 
    data = initData; 
    prev = initPrev; 
    next = initNext; 
    } 


    template <class T> 
    void Node<T>::setData(T newData) 
    { 
    data = newData; 
    } 


    template <class T> 
    T Node<T>::getData() 
    { 
    return data; 
    } 


    template <class T> 
    void Node<T>::setPrev(Node<T>* newPrev) 
    { 
    prev = newPrev; 
    } 


    template <class T> 
    Node<T>* Node<T>::getPrev() 
    { 
    return prev; 
    } 


    template <class T> 
    void Node<T>::setNext(Node<T>* newNext) 
    { 
    next = newNext; 
    } 


    template <class T> 
    Node<T>* Node<T>::getNext() 
    { 
    return next; 
    } 


    template <class T> 
    std::ostream& operator << (std::ostream& out, const Node<T>& a) 
    { 
    out << a->getData(); 
    return out; 
    } 

Когда я распечатать его с помощью

cout << "Initialised intNode with " << (intNode) << " ,\n"; 
cout << "Initialised stringNode with " << (stringNode) << " ,\n"; 
cout << "Intiialised accountNode with $" << (accountNode) << "." << endl; 

Выход

Initialised intNode with 0x7f9251c03950 , 
Initialised stringNode with 0x7f9251c03970 , 
Intiialised accountNode with $0x7f9251c039c0. 

Когда разыменования, здесь ошибка

Undefined symbols for architecture x86_64: 
    "law_lab07::operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, law_lab07::Node<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > const&)", referenced from: 
     _main in main.o 
    "law_lab07::operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, law_lab07::Node<law_lab07::Account> const&)", referenced from: 
     _main in main.o 
    "law_lab07::operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, law_lab07::Node<int> const&)", referenced from: 
     _main in main.o 
ld: symbol(s) not found for architecture x86_64 
clang: error: linker command failed with exit code 1 (use -v to see invocation) 
make: *** [runfile] Error 1 
+0

Проводка ошибок поможет. Но из того, что я вижу, вы реализуете шаблоны в файле cpp, когда они должны идти в файл заголовка. – 0x499602D2

+0

И при размещении ошибок, возможно, исправьте оператора вставки; у него отсутствует ссылка возврата. И я думаю, что вы найдете [** этот ответ на аналогичный вопрос **] (http://stackoverflow.com/questions/4660123/overloading-friend-operator-for-template-class/4661372#4661372) довольно-полезным. (этот ответ звездный, кстати). – WhozCraig

+0

Объявление вашего вставки также должно быть шаблоном. – 0x499602D2

ответ

1

Во-первых, всегда скомпилируйте с предупреждениями. GCC дал мне хорошие подсказки, и я считаю, что Кланг тоже это сделает.

У вас возникла проблема с определением вашего оператора, так как это не шаблонный друг. Пожалуйста, обратите внимание на http://en.cppreference.com/w/cpp/language/friend

Раствор ниже:

namespace myNamespace{ 

template <class T> 
class Node 
{ 
public: 
    Node(T const& initData, Node<T>* const& initPrev = NULL, Node<T>* const& initNext = NULL); 
    void setData(T newData); 
    T getData() const; 
    void setPrev(Node<T>* newPrev); 
    Node<T>* getPrev(); 
    void setNext(Node<T>* newNext); 
    Node<T>* getNext(); 

    friend std::ostream& operator<< (std::ostream& out, const Node& a) 
       { 
       return out << a.getData(); 
       } 

private: 
    T data; 
    Node<T> *next; 
    Node<T> *prev; 
}; 
#include "Node.template" 
} 
#endif 

Обратите внимание, что вы должны сделать свой метод GetData() константной один компилировать.

Также не забудьте разыменования указателя в основной, как предложено ранее другими:

cout << "Initialised intNode with " << (intNode)->getData() << " ,\n"; 
cout << "Initialised stringNode with " << stringNode->getData() << " ,\n"; 
cout << "Intiialised accountNode with $" << *accountNode << "." << endl; 

Это файл Account.h я сделал:

using namespace std; 

namespace myNamespace{ 
class Account 
{ 
    public: 
     Account(){} 
     Account(int initialValue); 
     void deposit(int amount); 
     void withdraw(int amount); 
     void setName(std::string newName); 
     int balance() const; 
     bool has_funds() const; 
     std::string getName(); 
     friend int& operator += (Account& a,const Account& b); 
     friend std::ostream& operator << (std::ostream& out, const Account& a); 

    protected: 
    private: 
     int acct_balance; 
     string name; 
}; 
} 
#endif // ACCOUNT_H 

добавить Также «return» в операторе < < Внедрение учетной записи

+0

Я не уверен, в чем проблема, но я получаю сообщение Инициализированный stringNode с приветствием, Ошибка сегментации: 11 fOrceez

+0

Не могли бы вы попытаться заменить a.getData() строкой «test \ n» в операторе << реализация? У меня нет проблем с кодом, который я скомпилировал. – Lectem

+0

Это работает отлично! Должно быть, что-то с моим классом «Учет»? – fOrceez

0

Я считаю, что проблема заключается в cout << "Intiialised accountNode with $" << accountNode << "." << endl;. Вы пытаетесь напечатать Node<Account>* вместо Node<Account>, для которого у вас нет перегрузки.

+0

Справа. Извините, я должен уточнить, что даже когда я разыскиваю свои указатели, я не могу распечатать их с помощью перегружателя:/Я отредактирую главный пост с моей ошибкой – fOrceez

Смежные вопросы