2012-02-17 75 views
0

我有这样的代码:呼叫子插入操作

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

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

操作系统 - Windows XP

在此先感谢。

+0

你会期待,而不是发生? – sth 2012-02-17 14:24:06

+0

main.cpp中的cout必须调用MySmartPtr.h中的overwitten运算符,它在Bean.h文件中调用覆盖的运算符。这是我的想法。 – 2012-02-17 14:26:29

回答

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,并且未能声明Beanoperator<<

这是你的程序的修正版本:

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; 
} 

为主。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 
+0

感谢它工作正常:) – 2012-02-17 14:33:24

+0

你能告诉我为什么第二个版本的MySmartPtr的作品? – 2012-02-17 14:34:49