有没有办法编写模板函数来处理智能指针和常规指针?
Posted
技术标签:
【中文标题】有没有办法编写模板函数来处理智能指针和常规指针?【英文标题】:is there a way to write a template function for dealing with smart pointer and regular pointer? 【发布时间】:2021-08-24 16:09:14 【问题描述】:请我尝试编写一个接受智能指针或常规指针向量的函数,但它永远不会工作,我想编写函数getLargestRadius()
接受作为参数std::vector<something*>
或std::vector<std::shared_ptr<something>>
。
它对我有用的唯一方法是重载函数
这是我的完整代码,可以准确理解我的意思:
#include <iostream>
#include <vector>
#include <memory>
class Point
private:
int m_x 0 ;
int m_y 0 ;
int m_z 0 ;
public:
Point() = default;
Point(int x, int y, int z)
: m_xx, m_yy, m_zz
friend std::ostream& operator<<(std::ostream &out, const Point &p)
out << "Point(" << p.m_x << ", " << p.m_y << ", " << p.m_z << ')';
return out;
;
class Shape
public:
virtual std::ostream& print(std::ostream &out) const = 0;
friend std::ostream& operator <<(std::ostream &out, const Shape &shape)
return shape.print(out);
virtual ~Shape()
;
class Triangle : public Shape
private:
Point m_a;
Point m_b;
Point m_c;
public:
Triangle(const Point &a, const Point &b, const Point &c)
: m_aa, m_bb, m_cc
virtual std::ostream& print(std::ostream &out) const override
out << "Trinagle(";
out << m_a << ", ";
out << m_b << ", ";
out << m_c << ")";
return out;
;
class Circle: public Shape
private:
Point m_center;
int m_radius;
public:
Circle(const Point ¢er, int radius)
: m_centercenter, m_radiusradius
virtual std::ostream& print(std::ostream &out) const override
out << "Circle(" << m_center << ", radius " << m_radius << ')';
return out;
int getRadius() const return m_radius;
;
int getLargestRadius(std::vector<std::shared_ptr<Shape>> &v)
int largestRadius 0 ;
for(int x0; x < static_cast<int>(v.size()); ++x)
if (dynamic_pointer_cast<Circle>(v[x]))
if (dynamic_cast<Circle&>(*v[x]).getRadius() > largestRadius)
largestRadius = dynamic_cast<Circle&>(*v[x]).getRadius();
return largestRadius;
int getLargestRadius(std::vector<Shape*> &v)
int largestRadius 0 ;
for(int x0; x < static_cast<int>(v.size()); ++x)
if (dynamic_cast<Circle*>(v[x]))
if (dynamic_cast<Circle*>(v[x])->getRadius() > largestRadius)
largestRadius = dynamic_cast<Circle*>(v[x])->getRadius();
return largestRadius;
int main()
std::vector<std::shared_ptr<Shape>> v1
std::make_shared<Circle>(Point1, 2, 3, 7),
std::make_shared<Triangle>(Point1, 2, 3, Point4, 5, 6, Point7, 8, 9),
std::make_shared<Circle>(Point4, 5, 6, 3)
;
std::vector<Shape*> v2
new CirclePoint1, 2, 3, 7,
new TrianglePoint1, 2, 3, Point4, 5, 6, Point7, 8, 9,
new CirclePoint4, 5, 6, 3
;
for(auto &element : v1)
std::cout << *element << '\n';
std::cout << "The largest radius is: " << getLargestRadius(v1) << '\n';
std::cout << "The largest radius is: " << getLargestRadius(v2) << '\n';
for(auto &element : v2)
delete element;
return 0;
我尝试将其作为模板,但没有任何效果。 如您所见,我必须重载该函数才能使其与两种向量类型一起使用 那么有没有办法使用模板使其只有一个函数适用于所有类型。
谢谢
【问题讨论】:
【参考方案1】:如果不检查,您可能会使用template
:
template <typename T>
int getLargestRadius(const std::vector<T>& v)
int largestRadius 0 ;
for (const auto& shapePtr : v)
if (const auto* circle = dynamic_cast<const Circle*>(&*shapePtr))
largestRadius = std::max(largestRadius , circle->radius);
return largestRadius;
为了平等对待常规指针和智能指针,我尊重它们 (*shapePtr
),所以我有一个参考。
(那我需要取回正则指针,所以我取地址&*shapePtr
)。
【讨论】:
非常感谢它确实有效,我只是觉得你错过了 type circle->getRadius() ,请你解释一下你为什么使用 &*e ? 我只想强调一下您如何使用取消引用的结果来获取 OP 的利益。以上是关于有没有办法编写模板函数来处理智能指针和常规指针?的主要内容,如果未能解决你的问题,请参考以下文章