繁体   English   中英

C ++中函数的自动返回类型

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM