调用子插入运算符

时间:2012-02-17 14:16:40

标签: c++ templates operator-overloading

我有一个代码:

的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&lt;&lt; const&gt;' :在所有控制路径上递归,函数将导致运行时堆栈溢出

当然,当我在main.cpp文件中的cout行中删除程序时,按F11,我将debuger转到覆盖的操作符函数中的MySmartPtr.h文件中。 并在行os << static_cast<const T>(o);中调用此运算符一次又一次地重载,因此我得到了堆栈重载异常。 我的问题是为什么会这样?

操作系统 - Windows XP

提前致谢。

1 个答案:

答案 0 :(得分:2)

  

为什么会这样?

得到应有的尊重,它正在发生,因为这就是你编码的内容。

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的{​​{1}}。

以下是您的计划的更正版本:

Bean.cpp

operator<<

的main.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;
 }

Bean.h

 #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 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