[英]Auto return type of a function in c++
我有一个我无法解决的问题。 我试图在这里找到类似的问题,但没有找到适合我的解决方案。
我的结构是:
class Base
{
unsigned int ID;
};
class Position: public Base
{
float x,y;
Position(float a, float b): x(a), y(b) {}
}
class Mass: public Base
{
float mass;
Mass(float a): mass(a) {}
}
我将指向所有属性的指针存储在带有字符串的映射中。 我想要一个函数,该函数可以使用名称从此列表返回任何属性。 结构和所需功能应如下所示:
std::map<string, Base*> attributes;
???? getAtt(string name)
{
return attributes[name];
}
Position pos(1,2);
Mass mass(25.6);
attributes.emplace("TEST_POSITION", &pos);
attributes.emplace("TEST_MASS") &mass);
cout << "Mass of this object is " <<getAtt("TEST_MASS").mass << endl;
cout << "X - Position of this object is " << getAtt("TEST_POSITION").x ;
PRINTS: Mass of this object is 25.6
X - Position of this object is 1
这个功能,属性的添加和内存管理应该封装在另一个类中,但是我认为在我解决了这个问题之后就不会出现这样的问题。 那么有没有办法做到这一点? 我在考虑模板,但是我对它们的理解不足以使它们工作:(我当时正在考虑不将所有属性存储在一个数组中,但是这样确实很容易。感谢任何建议:)
编译器无法在不提示的情况下推断出返回类型。 您可以为此使用模板:
template <typename T>
T& getAtt(string name)
{
return dynamic_cast<T&>(*attributes.at(name));
}
编辑:使用at
代替[]
, []
具有创建不存在的键的副作用。
然后这样称呼它:
getAtt<Mass>("TEST_MASS").mass
getAtt<Position>("TEST_POSITION").x
但是,此代码将成为调试的噩梦。 尽量避免使用通用属性,并使用强类型变量。 代替:
std::map<string, Base*> attributes;
attributes.emplace("mass", Mass(…));
attributes.emplace("position", Position(…));
采用:
Mass mass;
Position position;
您的getAtt将返回一个Base *,如下所示:
Base* getAtt(const string& name)
{
...
}
但是基类没有为其所有派生类提供接口,因此您不能只是做
getAtt("TEST_MASS").mass
相反,您必须这样做:
dynamic_cast<Mass*>(getAtt("TEST_MASS"))->mass;
dynamic_cast<Position*>(getAtt("TEST_POSITION"))->x;
还有其他选择,例如您可以使用带标签的联合,但是对于您的问题而言可能太复杂了。
顺便说一句,map的[]运算符将创建一个元素(如果不存在),因此您需要检查getAtt是否未返回nullptr。
您可以将具有转换运算符的引用对象返回给该类型。 如果转换是通过动态强制转换实现的,则尝试将对象分配给不是它的对象时,结果将为NULL。 动态强制转换要求Base
具有虚拟方法(您可以仅添加虚拟析构函数)。
class Base {
unsigned int ID;
protected:
virtual ~Base () {}
};
class Ref {
friend Ref getAtt (std::string name);
Base *ref_;
Ref (Base *p = 0) : ref_(p) {}
public:
template <typename D> operator D * () const {
return dynamic_cast<D *>(ref_);
}
};
Ref getAtt (std::string name) { return attributes[name]; }
此技术不允许您将Ref
视为任何特定类型。 它允许您将其分配给允许成为的对象。
Mass *m = getAtt("TEST_MASS");
Position *p = getAtt("TEST_POSITION");
cout << "Mass of this object is " << m->mass << endl;
cout << "X - Position of this object is " << p->x ;
如果结果指针为NULL,则意味着该项目不存在,或者您正尝试将其分配给错误的对象。
Position *p = getAtt("TEST_MASS");
assert(p == NULL);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.