创建一个从其他类成员自动计算的类成员?

Trv*_*ack 4 c++ class

  1. 在编程方面,我是一个绝对的新手,我试图通过解决C++中一些简单的"问题"来自学基础知识.

  2. 我已经在网上搜索了我的问题的确切答案,然后在这里发布并且到目前为止还没找到,但这可能是因为(1).

所以,我正在寻找的是一种声明一个类成员的方法,该类成员可以从同一个类的其他成员自动计算,因此计算出来的类成员可以像显式定义的类成员一样使用.例如,想象一个名为creature的结构,它具有属性/ members creature.numberofhands,creature.fingersperhand,最后是属性creature.totalfingers,它们自动从上面的成员计算出来.

以下是我最接近我想达到的目标的一个例子:

#include <iostream>

typedef struct creature {
    int numberofhands;
    int fingersperhand;
    int totalfingers();
} creature;    

int creature::totalfingers()
{
    return numberofhands * fingersperhand;
};

int main()
{
    creature human;
    human.numberofhands = 2;
    human.fingersperhand = 5;

    printf("%d",human.totalfingers());
    return(0);
}
Run Code Online (Sandbox Code Playgroud)

对此我真烦恼的是,我必须从明确定义的那个中处理计算出的一个,即我必须在它之后加上"()".我怎样才能更改代码,所以我可以使用:human.totalfingers而无需明确定义它?

Jes*_*uhl 5

最简单的选择是使用公共成员函数并隐藏实际属性.像这样的东西:

class Creature {
public:
    Creature(int numhands, int fingersperhand) // constructor
        : m_numhands{numhands}, m_fingersperhand{fingersperhand}
        { }
    int fingersPerHand() const { return m_fingersperhand; }
    int numberOfHands() const { return m_numhands; }
    int totalFingers() const { return numberOfHands() * fingersPerHand(); }

private:
    const int m_numhands;
    const int m_fingersperhand;
};
Run Code Online (Sandbox Code Playgroud)

私有成员变量是一个实现细节.该类的用户只需使用三个公共成员函数在构造后获得不同数量的手指,并且不需要关心其中两个手指返回常量存储的数字,而第三个返回计算值 - 这与用户无关.

使用示例:

#include <iostream>
int main()
{
    Creature human{2, 5};
    std::cout << "A human has "
        << human.totalFingers() << " fingers. "
        << human.fingersPerHand() << " on each of their "
        << human.numberOfHands() << " hands.\n";
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

如果 - 根据你的评论 - 你不想使用构造函数(虽然这是确保你不要忘记初始化成员的最安全的方法),你可以像这样修改类:

class CreatureV2 {
public:
    int fingersPerHand() const { return m_fingersperhand; }
    int numberOfHands() const { return m_numhands; }
    int totalFingers() const { return numberOfHands() * fingersPerHand(); }

    void setFingersPerHand(int num) { m_fingersperhand = num; }
    void setNumberOfHands(int num) { m_numhands = num; }

private:
    // Note: these are no longer `const` and I've given them default
    // values matching a human, so if you do nothing you'll get
    // human hands.
    int m_numhands = 2;
    int m_fingersperhand = 5;
};
Run Code Online (Sandbox Code Playgroud)

使用修改类的示例:

#include <iostream>
int main()
{
    CreatureV2 human;
    std::cout << "A human has "
        << human.totalFingers() << " fingers. "
        << human.fingersPerHand() << " on each of their "
        << human.numberOfHands() << " hands.\n";

    CreatureV2 monster;
    monster.setFingersPerHand(7);
    monster.setNumberOfHands(5);
    std::cout << "A monster has "
        << monster.totalFingers() << " fingers. "
        << monster.fingersPerHand() << " on each of their "
        << monster.numberOfHands() << " hands.\n";

    CreatureV2 freak;
    freak.setFingersPerHand(9);
    // Note: I forgot to specify the number of hands, so a freak get 
    // the default 2.
    std::cout << "A freak has "
        << freak.totalFingers() << " fingers. "
        << freak.fingersPerHand() << " on each of their "
        << freak.numberOfHands() << " hands.\n";

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

注意:以上所有假设您使用的是现代C++ 14编译器.