我有一个代码:
的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
提前致谢。
答案 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