Вызовите оператор вставки - PullRequest
0 голосов
/ 17 февраля 2012

У меня есть этот код:

main.cpp

     #include <iostream>
     #include "MySmartPtr.h"
     #include "Bean.h"
     using namespace std;
     int main(int argc,char* argv[])
     {
        MySmartPointer<Bean> ptr = new Bean;
        ptr->setName("Jordan Borisov");
        cout << ptr << endl;
        return 0;
     }

MySmartPtr.h

     #ifndef MY_SMART_POINTER_H
     #define MY_SMART_POINTER_H
     #include <iostream>
     using namespace std;
     template<typename T>
     ostream& operator<<(ostream& os,T& o);

     template<typename T>
     class MySmartPointer
     {
     public:
        MySmartPointer()
        {
              ptr = new T;
              isOwner = true;
        };
        MySmartPointer(T* t)
        :ptr(t)
        {
        }
        ~MySmartPointer()
        {
              if (isOwner) delete ptr;
        }
        const T* getPtr() const {return ptr;}
        T& operator* () {return *ptr;}
        T* operator->() {return ptr;}


     private:
        mutable bool isOwner;
        T* ptr;
     };
     template<typename T>
     ostream& operator<<(ostream& os,T& o)
     {
     os << static_cast<const T>(o);
     return os;
     };
     #endif

Bean.h

     #ifndef BEAN_H
     #define BEAN_H
     #include <string>
     #include <iostream>
     using namespace std;
     class Bean
     {
     public:
        Bean();
        void setName(const string& name);
        const string& getName() const;
     private:
        string name;
     };
     #endif

Bean.cpp

     #include "Bean.h"
     Bean::Bean()
     :name("")
     {
     }
     const string& Bean::getName() const
     {
        return name;
     }
     void Bean::setName(const string& name)
     {
        this->name = name;
     }
     ostream& operator<<(ostream& os,Bean& o)
     {
        os << "Name :" << o.getName();
        return os;
     }

Итак, проблема в том, что в Microsoft Visual Studio 2008 у меня есть это предупреждение:

предупреждение C4717: 'operator << const>': рекурсивно для всех путей управления, функция вызовет переполнение стека во время выполнения

и, конечно, когда я отлаживаю программу в строке cout в главномФайл .cpp Я нажимаю F11 и отладчик переходит в файл MySmartPtr.h в перезаписанной функции оператора.И в строке os << static_cast<const T>(o); снова и снова вызывайте перегрузку этого оператора, чтобы я получил исключение перегрузки стека.У меня вопрос, почему это происходит?

ОС - Windows XP

Заранее спасибо.

1 Ответ

2 голосов
/ 17 февраля 2012

почему это происходит?

При всем уважении, это происходит потому, что это то, что вы кодировали.

template<typename T>
 ostream& operator<<(ostream& os,T& o)
 {
   os << static_cast<const T>(o);
   return os;
 };

Вы написали рекурсивный шаблон функциидля operator<<, что применимо для каждого возможного типа.Это должно называть себя.Попробуйте вместо этого:

 template<typename T>
 std::ostream& operator<<(std::ostream& os,const MySmartPointer<T>& o);

Таким образом, ваш operator<< ограничен объектами, созданными из типов, созданных из вашего собственного шаблона, а не каждого объекта в системе .

В других новостях у вас также есть using namespace std в ваших заголовках, и вы не смогли объявить Bean s operator<<.

Вот исправленная версия вашей программы:

Bean.cpp

 #include "Bean.h"
 Bean::Bean()
 :name("")
 {
 }
 const std::string& Bean::getName() const
 {
    return name;
 }
 void Bean::setName(const std::string& name)
 {
    this->name = name;
 }
 std::ostream& operator<<(std::ostream& os,const Bean& o)
 {
    os << "Name :" << o.getName();
    return os;
 }

main.cpp

 #include <iostream>
 #include "MySmartPtr.h"
 #include "Bean.h"
 using namespace std;
 int main(int argc,char* argv[])
 {
    MySmartPointer<Bean> ptr = new Bean;
    ptr->setName("Jordan Borisov");
    cout << ptr << endl;
    return 0;
 }

Bean.h

 #ifndef BEAN_H
 #define BEAN_H
 #include <string>
 #include <iostream>
 class Bean
 {
 public:
    Bean();
    void setName(const std::string& name);
    const std::string& getName() const;
 private:
    std::string name;
 };
 std::ostream& operator<<(std::ostream&, const Bean&);
 #endif

MySmartPtr.h

 #ifndef MY_SMART_POINTER_H
 #define MY_SMART_POINTER_H
 #include <iostream>

 template<typename T>
 class MySmartPointer
 {
 public:
    MySmartPointer()
    {
          ptr = new T;
          isOwner = true;
    };
    MySmartPointer(T* t)
    :ptr(t)
    {
    }
    ~MySmartPointer()
    {
          if (isOwner) delete ptr;
    }
    T* getPtr() {return ptr;}
    T& operator* () {return *ptr;}
    T* operator->() {return ptr;}
    const T* getPtr() const {return ptr;}
    const T& operator* () const {return *ptr;}
    const T* operator->() const {return ptr;}

 private:
    mutable bool isOwner;
    T* ptr;
 };
 template<typename T>
 std::ostream& operator<<(std::ostream& os,const MySmartPointer<T>& o)
 {
 os << *o;
 return os;
 }
 #endif
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...