我想创建一个返回模板类对象共享指针的函数:
#include <memory>
template <class T>
class Rectangular
{
public:
virtual T& getHight() = 0;
virtual T& getWidth() = 0;
virtual Rectangular<std::shared_ptr<T>>* getPtr() = 0;
};
template <class T>
class Square:public Rectangular<T>
{
public:
Square() {};
Square(T hight, T width) :m_hight(hight), m_width(width) {};
T& getHight() ;
T& getWidth() ;
Square<std::shared_ptr<T>>* getPtr() ;
public:
T m_hight;
T m_width;
};
template <class T>
T& Square<T>::getHight() { return m_hight; };
template <class T>
T& Square<T>::getWidth() { return m_width; };
template <class T>
Square<std::shared_ptr<T>>* Square<T>::getPtr() { return this; };
int main()
{
Square <double> sq(5,3);
std::cout << sq.getPtr()->getHight();
return 0;
}
这是我得到的运行时错误:
递归类型或函数依赖上下文太复杂。
有人可以帮助我了解发生了什么事吗?
答案 0 :(得分:4)
您无法无处提高共享所有权。 Rectangular::getPtr
无法正常工作。没有shared_ptr
可以从sq
获取,它是main
唯一拥有的 。
您还对如何组合模板感到困惑。 Square<std::shared_ptr<T>>
是一个正方形,其宽度和高度为std::shared_ptr<T>
s,大概指向无关的数据。您可能的意思是std::shared_ptr<Square<T>>
,它是代表正方形所有权份额的对象。
最后,虽然数学上所有正方形都是矩形,但您不能将可修改正方形与可修改矩形互换使用。根据定义,正方形的宽度和高度相等。更改矩形的宽度不应更改其高度。
这两个要求存在矛盾。
答案 1 :(得分:3)
template <class T>
Square<std::shared_ptr<T>>* Square<T>::getPtr() { return this; }
这将返回Square<std::shared_ptr<T>>*
,其中T
是double
,所以Square<std::shared_ptr<double>>*
。编译器必须为您Square
实例化此模板。
此新实例还具有方法getPtr
,该方法现在返回Square<std::shared_ptr<std::shared_ptr<double>>*
。编译器必须为您Square
实例化此模板。
重复此过程,直到编译器完成工作或崩溃为止。
这是无限递归的,永远不会起作用。您应该重新考虑您的设计。
答案 2 :(得分:1)
打开此声明
Square<std::shared_ptr<T>>* getPtr() ;
对此
Rectangular<std::shared_ptr<T>>* getPtr() ;
为什么?因为尽管C ++允许使用协变量返回类型,但需要检查我们指向的完整对象类型是否存在协变量(类的基仅在完整类型中可见)。这就需要实例化,然后Sombrero Chicken answered就会发生。
但是,如果您不使用covaraint返回类型,则您不需要完成您指定的专业化。毕竟,因为我们可以形成指向不完整类类型的指针。一般来说。只要不需要完整的对象类型,命名特殊化就不会实例化该类。这样可以避免无限递归。
在其他答案中,我不会重复您设计中的其他要点。这仅仅是为了让您知道根本原因是什么。